[英]State was mutated as a side effect?
我的代碼遇到了一個奇怪的問題。 對不起,如果這已經被問到,我想搜索原因,但我什至不知道如何表述這個問題。
本質上,我有一個與此類似的代碼:
class Component extends Component {
constructor(props) {
super(props);
this.state = { grid: [["", "", "", ""]], base: ["", "", "", ""]};
}
csvParse = (row, column) => e => {
const newData = Papa.parse(e.target.value).data.filter(
x => x.length !== 1 && x[0] !== ""
);
//newData will result in a 2D array such as [["1", "2", "3", "4"], ["5", "6", "7", "8"], ["9", "10", "11", "12"]]
//newData is receiving the data from a copy and paste from a CSV file
const { base } = this.state;
let grid = this.state.grid
for (let i = row; i < newData.length + row; i++) {
for (let j = column; j < 4; j++) {
try {
grid[i][j] = newData[i][j];//1
} catch (err) {
grid.push(base);//2
grid[i][j] = newData[i][j];//3 One of these is causing it, I don't know which
}
}
}
this.setState({grid},()=>{
console.log(this.state.base)
//Actually logs ["9", "10", "11", "12"] instead of ["", "", "", ""]. Why was it mutated?
})
};
render() {
//The component renders a 4 X 1 grid of textareas. The number of rows will increase based on this.state.grid. Doesn't seem like its the issue.
return (
<Fragment>
<Grid container>
{this.state.grid.map((row, rowIndex) => (
<Fragment key={rowIndex}>
<Grid item xs={3}>
<textarea
onChange={this.csvParse(rowIndex, 0)}
value={row[0]}
/>
</Grid>
<Grid item xs={3}>
<textarea
onChange={this.csvParse(rowIndex, 1)}
value={row[1]}
/>
</Grid>
<Grid item xs={3}>
<textarea
onChange={this.csvParse(rowIndex, 2)}
value={row[2]}
/>
</Grid>
<Grid item xs={3}>
<textarea
onChange={this.csvParse(rowIndex, 3)}
value={row[3]}
/>
</Grid>
</Fragment>
))}
</Grid>
</Fragment>
);
}
}
每次我運行它時 this.state.base 都會變成別的東西,比如 [""]。 如果我在沒有 this.state.base 的情況下運行它,此代碼沒有問題
啊,我相信你希望state.base
保持['','','','']
。 如果是這種情況,請繼續閱讀。 否則讓我知道,我們可以迭代。
要了解state.base
發生了什么變化,您需要了解按引用傳遞和按值傳遞之間的區別。
基本上在按引用傳遞,如果你創建一個變量a
,然后創建一個變量b
等於a
,然后更改鍵/值的值a
,您還可以改變b
:
var a = {'hi': 'mom'}
var b = a;
a['hi'] = 'world';
console.log(b);
// logs {hi: 'world'}
在按值傳遞,如果你創建一個變量a
,然后創建一個變量b
等於a
,然后更改的值a
,你都不會改變b
:
var a = true;
var b = a;
a = false;
console.log(b);
// logs true;
對象{}
和數組[]
在 JavaScript 中是按引用傳遞的,大多數其他原始數據類型是按值傳遞。 這是語言本身一個奇怪但至關重要的方面,它改變了我們編寫 React 的方式。
在您的情況下,您將state.base
分配給base
,然后將base
添加到grid
,然后更改grid
。 state.base
發生變異只是時間問題。
為避免這種情況,只需更改:
grid.push(base);
到:
grid.push(Object.assign([], base));
此處的對象分配將創建一個值為base 的新變量,並將其添加到網格中。 這可以防止對grid
任何更改修改state.base
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.