我不明白为什么下面的代码不会改变状态。即使执行“if”语句,状态也是一样的。为什么 if
的大小写不会改变状态?
class Welcome extends React.Component {
state = {
items: [
{
id: 1,
done: false,
},
{
id: 2,
done: false,
},
{
id: 3,
done: false,
},
]
}
handleDone = (index) => {
this.setState((prevState) => {
const copyItems = [...prevState.items];
if (copyItems[index].done === false) {
console.log("Done should be true");
copyItems[index].done = true;
} else {
console.log("Done should be false");
copyItems[index].done = false;
}
// copyItems[index].done = !copyItems[index].done - the same result
return {
items: [...copyItems],
};
});
}
render() {
return (
this.state.items.map((item, index) => {
return (
<div>
<span>id: {item.id}</span>
<span> {item.done ? "- is not done" : "- is done"} </span>
<button
onClick={() => this.handleDone(index)}>
Change to opposite
</button>
</div>
)
})
)
}
}
ReactDOM.render(<Welcome />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
this.setState((prevState) => {
const copyItems = [...prevState.items];
if (copyItems[index].done === false) {
console.log("Done should be true");
copyItems[index].done = true;
} else {
console.log("Done should be false");
copyItems[index].done = false;
}
// copyItems[index].done = !copyItems[index].done - the same result
return {
items: [...copyItems],
};
});
当没有 if
语句时,下面的示例工作正常:
this.setState((prevState) => {
const copyItems = [...prevState.items];
copyItems[index].done = true;
return {
items: [...copyItems],
};
});
如果复制对象,下面的示例可以很好地与 'if' 语句一起使用:
this.setState((prevState) => {
const copyItems = JSON.parse(JSON.stringify([...prevState.items]));
copyItems[index].done = !copyItems[index].done
return {
items: [...copyItems],
};
});
答案 0 :(得分:1)
React 的错误在于,即使您展开数组,其中的对象仍会被引用为您状态中的对象。因此,通过执行 copyItems[index].done = true;
您实际上是在直接改变状态(this.state[index].done 也应该是真的)。为了避免这种情况,您可以做的是在 prevState 上使用 .map,这样您就不会直接更新状态。
const state = [{ done: true }];
const stateCopy = [...state];
const toFind = 0;
stateCopy[toFind].done = false;
console.log(stateCopy[toFind], state[toFind]); // { done: false } , { done: false } /!\ state should not be updated at this point.
// good way of doing that might be by using prevState.items.map() and do your logic inside it
const stateUpdated = state.map((el, index) => {
if (index === toFind) {
return { done: !el.done }
}
return el;
});
console.log(stateUpdated[toFind], state[toFind]) // state is not mutated, as expected
答案 1 :(得分:-1)
问题是由使用 import sys
T = int(input())
for lines in sys.stdin:
print(lines[::2]+ " " + lines[1::2])
包装应用程序的 create-react-app 引起的。
要解决它,只需删除此包装标签。就是这样。 这是预期的行为,它应该有助于避免产品上的错误。 React docs 中的更多详细信息。