我的构造函数中有以下代码:
this.state = {
tests: [
{
question: "1",
answer: "2",
user: ""
},
{
question: "1",
answer: "2",
user: ""
},
],
};
我具有编辑功能,可以在输入中读取事件值:
edit(id, event) {
this.state.tests[id].user = event.target.value;
this.setState({tests:this.state.tests});
}
但是es给我这个警告:
请勿直接更改状态。使用
setState()
反应/无直接突变状态
在这种情况下我该怎么办?也许以某种方式将分配为event.target.value
的行更改为setState()
?
答案 0 :(得分:2)
您可以使用interface Model { side: 'left' | 'right'; }
interface LeftModel extends Model { side: 'left'; }
interface RightModel extends Model { side: 'right'; }
function isLeft(value: Model): value is LeftModel {
return value.side === 'left';
}
function whatever(model: LeftModel | RightModel) { // This union makes the else branch work
model.side // left or right
if (isLeft(model)) {
model.side; // left - model is also LeftModel at this point
} else {
model.side; // right - model is a RightModel
}
}
创建map()
的副本
tests
答案 1 :(得分:1)
我倾向于的一种方法是先复制数组,然后更改其中的一项,或者更改数组本身,然后设置状态
var tests = this.state.tests.slice(0);
tests[id].user = event.target.value;
this.setState({tests:tests});
在某些情况下,您可能想深度克隆数组,有时不希望。
答案 2 :(得分:0)
您是对的,问题出在线路上
this.state.tests[id].user = event.target.value;
这就是您直接改变状态的地方。
您有一些选择。
您可以先“克隆”阵列,然后更新它:
const newTests = [...this.state.tests];
newTests[id].user = event.target.value;
this.setState({tests: newTests});
您也可以使用immutability-helper
:
const {value} = event.target;
this.setState(prevState => update(prevState, {[id]: {user: {$set: value}}}));
在此示例中,您需要从事件中提取value
,因为在处理事件后访问异步调用中的事件值并不安全。
答案 3 :(得分:0)
edit(id, event) {
var newNote = {...this.state.tests[id]}
newNote.user = event.target.value
this.setState({ tests: [...this.state.tests, newNote]})
}
答案 4 :(得分:0)
当状态不太沉重时,我使用以下代码:
edit (id, event) {
const cp = JSON.parse(JSON.stringify(this.state.tests))
cp[id].user = event.target.value
this.setState({ tests: cp })
}
更新:我发现Immer完美解决了这个问题。
import produce from 'immer'
edit (id, event) {
this.setState(
produce(draft => draft.tests[id].user = event.target.value)
)
}
答案 5 :(得分:0)
首先,当您尝试使用先前状态中的数据设置新状态时,必须使用更新程序 https://reactjs.org/docs/react-component.html#setstate
const edit = (id, event) => {
this.setState((prevState) => {
const tests = [...prevState.tests];
tests[id] = {
...tests[id],
user: event.target.value
};
return {
...prevState,
tests
};
});
};