![](/img/trans.png)
[英]Am I mutating my reducer state by replacing an entire array in an object?
[英]am I mutating object?
我正在改變狀態對象嗎
state = {
selectedHero: { id: "", name: "", saying: "" }
}
用這種方法
handleChange = e => {
let selectedHero = this.state.selectedHero;
selectedHero[e.target.name] = e.target.value;
this.setState({ selectedHero });
};
我應該寫這樣的東西嗎?
handleChange = e => {
let selectedHero = { ...this.state.selectedHero };
selectedHero[e.target.name] = e.target.value;
this.setState({ selectedHero });
};
是的,沒有。 您不是要this.state
,而是要this.state
引用的對象。 在React中不應該這樣做。
我應該寫這樣的東西嗎?
差不多 ; 由於這涉及基於狀態( selectedHero
的其他屬性)來更新狀態,因此必須使用setState
的回調版本 。 由於這意味着在handleChange
返回后使用合成事件中的屬性,因此我們需要handleChange
獲取它們:
handleChange = e => {
const {name, value } = e.target;
this.setState(prevState => {
let selectedHero = { ...prevState.selectedHero };
selectedHero[name] = value;
return { selectedHero };
})
};
如果您不使用回調版本,則大多數情況下似乎會正常工作,並且在對selectedHero
進行重疊的狀態更新時會失敗(請記住狀態更新是異步的); 一個會腳另一個。
如果您願意,還可以通過在屬性分布后使用計算的屬性名稱來壓縮它:
handleChange = e => {
const {name, value} = e.target;
this.setState(prevState => ({selectedHero: {...prevState.selectedHero, [name]: value}}));
};
甚至拋出一些參數解構:
handleChange = ({target: {name, value}}) => {
this.setState(prevState => ({selectedHero: {...prevState.selectedHero, [name]: value}}));
};
(是的,解構將在handleChange
返回之前發生。它發生在handleChange
的顯式代碼handleChange
運行之前。)
是的,您正在變異selectedHero
對象。 您應該執行以下操作:
handleChange = e => {
let selectedHero = Object.assign({}, this.state.selectedHero);
selectedHero[e.target.name] = e.target.value;
this.setState({ selectedHero });
};
Object.assign
調用將創建一個新對象,這樣就不會修改您原來的selectedHero對象。
編輯:您對ES2018傳播語法的編輯使用也可以使用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.