![](/img/trans.png)
[英]How to combine Material-UI's snackbar and input components in react?
[英]How can I use React Material UI's transition components to animate adding an item to a list?
我有這個 class。
class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {
items: []
};
this.add = this.add.bind(this);
this.clear = this.clear.bind(this);
}
add() {
this.setState(prev => {
const n = prev.items.length;
return {
items: [<li key={n}>Hello, World {n}!</li>, ...prev.items]
};
});
}
clear() {
this.setState({ items: [] });
}
render() {
return (
<div>
<div>
<button onClick={this.add}>Add</button>
<button onClick={this.clear}>Clear</button>
</div>
{/* This is wrong, not sure what to do though... */}
<Collapse in={this.state.items.length > 0}>
<ul>{this.state.items}</ul>
</Collapse>
</div>
);
}
}
沙盒鏈接: https://codesandbox.io/s/material-demo-ggv04?file=/Demo.js
我正在努力做到這一點,以便每次單擊“添加”按鈕時,一個新項目會在列表頂部以動畫方式存在,並且現有項目會被下推。 不知道如何進行。
額外資源
Collapse
在內部使用)我更新了你的沙盒代碼來實現你想要的,但我不認為 MaterialUI 是最好的庫(我可能會錯過更好的方法)。
挑戰在於,當您添加新項目時,DOM 中尚不存在該項目。 並且大多數 animation 庫/組件要求元素位於 DOM 中,它們只是“隱藏”和“顯示”它並帶有過渡時間。
我遇到了類似的情況,經過一些研究,我發現可以處理 animation 的更好的庫是Framer Motion 。 (您可以查看他們的 安裝動畫文檔)
無論如何,這里是新代碼沙箱的鏈接,所以你可以看看。 我所做的更改:
刪除了隨機密鑰
In the map
function that creates your list using the <Collapse />
component, there was a function to get a random integer and assign that as a key
to your component. React 需要有一致的鍵才能正確地進行偽裝,因此刪除該隨機數可以解決您的“切換”按鈕沒有正確動畫的問題。 (如果您的項目列表沒有唯一 ID,只需使用map
function 的索引,這不是一個好的解決方案,但仍然比隨機數好)。
<Collapse key={i} timeout={this.state.collapseTimeout} in={this.state.open}>
{it}
</Collapse>
添加了一個新的 function 來控制切換
這里的方法是:在列表中添加項目,在元素進入 DOM 后,關閉<Collapse />
,稍等片刻,然后再次打開它(這樣你就可以直觀地看到動畫)。 為了做到這一點,我們需要一個新的“切換” function 可以顯式設置折疊的值。
toggleValue(value) {
this.setState(() => {
return {
open: value
};
});
}
為崩潰添加了可變超時
最后一個問題是,在添加新項目時關閉<Collapse />
會觸發 animation 將其關閉。 這里的解決方案是動態改變崩潰的超時時間,所以你看不到。
setCollapseTimeout(value) {
this.setState(() => {
return {
collapseTimeout: value
};
});
}
將元素添加到列表時,等待觸發 animation同樣,要解決尚未在 DOM 中的元素的問題,我們需要使用setTimeout
或其他東西來等待切換<Collapse />
。 這是在您的add()
function 中添加的。
add() {
this.toggleValue(false);
this.setCollapseTimeout(0);
this.setState(prev => {
const n = prev.items.length;
return {
items: [<li key={n}>Hello, World {n}!</li>, ...prev.items]
};
});
setTimeout(() => {
this.setCollapseTimeout(300);
this.toggleValue(true);
}, 100);
}
同樣,這是一個讓 MaterialUI 中的<Collapse />
與尚未在 DOM 中的元素一起工作的 hacky 解決方案。 但是,如前所述,還有其他更好的庫。
祝你好運:)
早些時候在這里結束,然后回來創建一個沙箱,希望能展示一種適用於這種情況的簡單方法。 material-ui
文檔在這方面有點(很多)輕松,我正在與非常相似的情況作斗爭,但我嘗試了react-transition-group
中的TransitionGroup
,交叉手指,它似乎有效。
帶有 TransitionGroup 的分叉 CodeSandbox
要點是你
<TransitionGroup>
組件中包裝你想要過渡的所有組件TransitionGroup
中,為要渲染的數據輸入“條件”(邏輯或循環輸出)<Collapse>
例如,在其最簡單的設置中,“項目”是來自任一道具的唯一數字數組,state 或 redux 商店
<TransitionGroup>
{items.map(item => (
<Collapse key={item}>
I am item {item}
</Collapse>
))}
</TransitionGroup>
通過這個設置,我發現我不需要在TransitionGroup
或Collapse
上放置任何道具,並且TransitionGroup
處理了循環渲染中的所有安裝和卸載。 Material UI 不會產生最輕的 HTML output,但我想這一切都是即時渲染的,所以也許這會讓它變得更好(除非你有數千個元素,然后事情開始拖累)。
您甚至可以進一步 go 並將整個事物包裝在另一個TransitionGroup
中,以涵蓋您想要刪除整個事物而不轉換所有單個項目的情況 - 在這種情況下,我將其切換為<Slide>
。 我絕對確定這行不通,但它似乎不在乎。 您也可以嘗試語義化並使用“組件”屬性,而不是包裝在另一個元素中,例如
<TransitionGroup>
{items.length > 0 && (
<Slide>
<TransitionGroup component="ul">
{items.map((item) => (
<Collapse component="li" key={item}>I am item {item}</Collapse>
))}
</TransitionGroup>
</Slide>
)}
</TransitionGroup>
我通過以下方式更改了沙箱
react-transition-group
TransitionGroup
Math.random
,但我想要一個“更漂亮”的輸出)。 通常,您的項目可能來自已設置唯一 ID 的數據庫。<TransitionGroup>
中,以表明卸載可以發生在組級別希望這對將來的某人有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.