[英]How to fix Do not mutate state directly. Use setState() with array?
[英]How to use setState to splice into an array in the state?
我的 state.events 在由組件實例組成的數組中:EventContainer。
我希望我的 setState 在 state.events 數組中放置一個新的 EventContainer。 但是,我希望 EventContainer 到 go 的索引中緊跟在進行 setState 調用的特定 EventContainer 之后。
我正在尋求對我的方法進行必要調整的幫助,或者,如果我的整個方法不好,我正在尋求關於如何 go 的建議。 非常感謝。
我正在開發一個行程構建器,它由代表給定日期的活動的行/事件容器組成。
每個 EventContainer 都有一個按鈕,需要讓用戶能夠在該 EventContainer 之后立即添加一行 onClick。
class DayContainer extends React.Component {
constructor(props){
super(props);
this.state = {
events: [],
};
this.pushNewEventContainerToState = this.pushNewEventContainerToState.bind(this);
}
pushNewEventContainerToState (index){
let newEvent = <EventContainer />;
this.setState(prevState => {
const events = prevState.events.map((item, j) => {
if (j === index) {
events: [...prevState.events.splice(index, 0, newEvent)]
}
})
})
}
render(){
return (
<>
<div>
<ul>
{
this.state.events === null
? <EventContainer pushNewEventContainerToState= .
{this.pushNewEventContainerToState} />
: <NewEventButton pushNewEventContainerToState={this.pushNewEventContainerToState} />
}
{this.state.events.map((item, index) => (
<li
key={item}
onClick={() =>
this.pushNewEventContainerToState(index)}
>{item}</li>
))}
</ul>
</div>
</>
)
}
}
我在 setState 中的目標是在索引之后立即將 newEvent 拼接到 this.state.events 中(pushNewEventContainerToState 函數中的參數)。
我收到了這個錯誤,但我猜還有比這更多的事情發生:第 23:22 行:預期分配或 function 調用,而是看到一個表達式 no-unused-expressions。
我可以看到代碼至少有 2 個問題。 - Splice 將在原地改變數組 - 您不會返回更新的 state。
您可以改為使用slice
來構建新數組。
pushNewEventContainerToState(index) { let newEvent = < EventContainer / >; this.setState(prevState => { const updatedEvents = [...prevState.events.slice(0, index], newEvent, ...prevState.events.slice(index + 1]; return { events: updatedEvents }) }) }
由於我對編碼還很陌生,所以我花了一些時間,但我能夠編譯出完整的答案。 這是代碼,如下。 在此之下,我將逐點解釋問題所在以及更新后的代碼如何解決該問題。
class DayContainer extends React.Component {
constructor(props){
super(props);
this.state = {
events: [{key:0}],
};
this.pushNewEventContainerToState = this.pushNewEventContainerToState.bind(this);
}
pushNewEventContainerToState(index) {
let newEvent = {key: this.state.events.length};
this.setState(prevState => {
let updatedEvents = [...prevState.events.slice(0, index + 1), newEvent, ...prevState.events.slice(index + 1)];
return {
events: updatedEvents
};
})
}
render(){
return (
<>
<div>
<ul>
{this.state.events.map((item, index) => (
<li key={item.key}>
< EventContainer pushNewEventContainerToState={() => this.pushNewEventContainerToState(index) } / >
</li>
))}
</ul>
</div>
</>
)
}
}
設置
從 state.events 開始,而不是從一個空數組開始,我從一個object開始,包括一個從 0 開始的鍵,因為我總是希望用戶從一個 EventContainer 開始。
關於 pushNewEventContainerToState ,@Sushanth 提出了很好的建議。 請直接參考我最新代碼中的function。 我所做的改進與我分離傳遞給 this.state.events 的 EventContainer 的方式有關。 我已將 EventContainer 從 pushNewEventContainerToState 移至 render() 元素。 我給了它一個 key={item.key} 的 prop 並將組件實例包裝在一個 li 中。 第一個 EventContainer 的鍵值為 0(參見 state.events[0])。 現在,傳遞給 state.events 的每個新 EventContainer 都將具有一個基於 state.events 數組的 latest.length() 的鍵(請參閱 pushNewEventContainerToState 中 let newEvent 變量的最新值)。
所有這些讓我解決了我面臨的一個大問題:我需要在調用 pushNewEventContainerToState 的 EventContainer 的索引之后立即將最新的 EventContainer 放入索引中。 發生這種情況的主要原因是我沒有正確地將索引傳遞給 render() 內部的 EventContainer。 現在我已經有了實際的 EventContainer,我可以以正確的方式向它傳遞一個道具(請參閱渲染中的 EventContainer 的道具)。 現在我用正確的索引調用 pushNewEventContainerToState。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.