我的代码遇到了一个奇怪的问题。抱歉,如果已经问过这个问题,我想搜索原因,但我什至不知道如何表达问题。
基本上,我有一个类似于以下代码:
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
的情况下运行此代码,则没有问题答案 0 :(得分:2)
啊,我相信您希望state.base
保持['','','','']
。如果是这样,请继续阅读。否则让我知道,我们可以迭代。
要了解state.base
的变化,您需要了解按引用传递和按值传递之间的区别。
本质上是通过引用传递的,如果您创建变量a
,然后创建变量b
等于a
,然后更改{{1 }},您还将更改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);
此处分配对象将创建一个新变量,其 value 为base,并将其添加到网格中。这样可以防止对grid.push(Object.assign([], base));
所做的任何更改都可以修改grid
。