Javascript 国家作为副作用发生了变异?
我的代码遇到了一个奇怪的问题。对不起,如果已经有人问了,我想查找原因,但我甚至不知道如何表达这个问题 基本上,我有一个类似的代码:Javascript 国家作为副作用发生了变异?,javascript,reactjs,Javascript,Reactjs,我的代码遇到了一个奇怪的问题。对不起,如果已经有人问了,我想查找原因,但我甚至不知道如何表达这个问题 基本上,我有一个类似的代码: class Component extends Component { constructor(props) { super(props); this.state = { grid: [["", "", "", ""]], base: ["", "", "", ""]}; } csvParse = (row, column) => e =&g
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={grid:[[“”、“”、“”、“”、“”]],base:[“”、“”、“”、“”]};
}
csvParse=(行、列)=>e=>{
const newData=Papa.parse(e.target.value).data.filter(
x=>x.length!==1&&x[0]!===“”
);
//新数据将生成一个二维数组,如[[“1”、“2”、“3”、“4”]、[“5”、“6”、“7”、“8”]、[“9”、“10”、“11”、“12”]]
//newData从CSV文件的复制和粘贴接收数据
const{base}=this.state;
让grid=this.state.grid
for(设i=row;i{
console.log(this.state.base)
//实际上记录的是[“9”、“10”、“11”、“12”]而不是[“”、“”、“”、“”、“”]。为什么会发生变异?
})
};
render(){
//该组件呈现一个4 X 1的文本区域网格。行数将在此基础上增加。state.grid似乎不是问题所在。
返回(
{this.state.grid.map((行,行索引)=>(
))}
);
}
}
每次我运行它时,this.state.base都会更改为其他内容,如[“”]。如果我在没有这个.state.base的情况下运行它,那么这个代码就没有问题了。啊,我相信您希望
state.base
保持['','','','',]
。如果是这样,请继续阅读。否则让我知道,我们可以迭代
要了解state.base的变化情况,您需要了解按引用传递和按值传递之间的区别
按参考传递与按值传递
基本上在传递引用中,如果您创建一个变量a
,然后创建一个等于a
的变量b
,然后更改a
中的键/值,您还将更改b
:
var a = {'hi': 'mom'}
var b = a;
a['hi'] = 'world';
console.log(b);
// logs {hi: 'world'}
var a = true;
var b = a;
a = false;
console.log(b);
// logs true;
在传递值中,如果创建变量a
,然后创建等于a
的变量b
,然后更改a
的值,则不会更改b
:
var a = {'hi': 'mom'}
var b = a;
a['hi'] = 'world';
console.log(b);
// logs {hi: 'world'}
var a = true;
var b = a;
a = false;
console.log(b);
// logs true;
对象{}
和数组[]
在JavaScript中是按引用传递的,大多数其他基本数据类型是按值传递的。这是语言本身一个奇怪但至关重要的方面,它改变了我们写作的方式
这如何适用于你的情况
在本例中,您将state.base
分配给base
,然后将base
添加到网格
,然后对网格
进行变异。state.base
发生变异只是时间问题
要避免这种情况,只需更改:
grid.push(base);
致:
这里的对象赋值将创建一个值为base的新变量,并将其添加到网格中。这可以防止对
网格的任何更改修改状态.base
要避免状态突变,请在将状态复制到要突变的对象时使用对象.assign({},mydict)
。Object.assign将返回一个新对象,其值在mydict
中。否则JS会对对象使用pass-by-reference,因此您将改变您的状态并导致许多副作用。此外,尝试将此代码示例缩减到尽可能少的行数也会对您有所帮助。这将帮助您隔离问题。一旦问题被隔离,您将能够更快地诊断和解决它。一个简单的例子对你的帮助比它对我们的帮助更大……你是对的,我发布了太多的代码。我缩短了它,并补充了我认为问题所在的地方。我还是不明白为什么碱基会变异,我并没有“碰”它?array.push()会导致什么吗?这些更新实际上使其他人更难再现您的情况,因为它不是一个可行的组件。你能发布显示你状态的最小可行组件吗?如果您可以删除CSV解析,并且仍然演示问题,那么就很容易弄清楚发生了什么。如果你也可以提供你的CSV内容,这将有助于。非常感谢你与我的轴承。我又编辑了一遍。希望这次很好。谢谢你的编辑,但我仍然无法复制,因为我无法访问你的数据。这是否显示了问题?如果你能最小限度地修改它来演示我们可以调试的问题。另外,为什么不一下子构建2d数组,然后将完整的2d数组传递给渲染函数呢?这将防止您多次重新计算相同的值,并将简化您认为困扰您的try/catch块yes。这就是我要找的。非常感谢。@Zymptom谢谢!我很高兴我们找到了真相!