不要直接改变状态,在 React JS 中使用 setState() react/no-direct-mutation-state

Posted

技术标签:

【中文标题】不要直接改变状态,在 React JS 中使用 setState() react/no-direct-mutation-state【英文标题】:Do not mutate state directly, Use setState() react/no-direct-mutation-state in React JS 【发布时间】:2017-09-27 06:11:45 【问题描述】:
<input
  defaultValue=this.props.str.name
  ref=(input) =>  this.state.name = input; 
  name="name"
  type="text"
  className="form-control"
  onChange=this.handleInputChange
/> 

handleInputChange(event) 
  this.setState(
    [event.target.name]: event.target.value
  );


if(this.state.name.value === "") 
  this.msg.show('Required fields can not be empty', 
    time: 2000,
    type: 'info',
    icon: <img src="img/avatars/info.png" role="presentation"/>
  );

我正在尝试像这样设置默认值,并且也想访问它。我确实喜欢这个并使用this.state.name.value 访问了该值,但事情是它的工作,但显示警告为

不要直接改变状态,使用 setState() 反应/无直接突变状态。

【问题讨论】:

你读过错误吗?不要直接修改状态对象,除非在构造函数中,使用this.setState( name: input ); "但是如果用户更改字段的值,我会使用那个东西" handleInputChange(event) this.setState( [event.target.name]: event.target.value ); 【参考方案1】:

得到“不要直接改变状态,使用 setState()”,为什么?

因为,你在 ref 回调方法中改变状态值来存储节点 ref,这里:

this.state.name = input;

解决方案:

不要使用状态变量来存储引用,可以直接存储 它们在组件实例中,因为这不会随着时间而改变。

根据DOC

状态包含特定于该组件的可能更改的数据 随着时间的推移。状态是用户定义的,它应该是一个普通的 javascript 对象。

如果你不在 render() 中使用它,它不应该在 state 中。为了 例如,您可以将计时器 ID 直接放在实例上。

由于您使用的是 controlled input element,因此不需要 ref。直接使用this.state.name与输入元素值属性和this.state.name访问值。

使用这个:

<input
    value=this.state.name || ''
    name="name"
    type="text"
    className="form-control"
    onChange=this.handleInputChange 
/>

如果您想使用ref,则直接将引用存储在实例上,删除 value 属性,您也可以删除 onChange 事件,像这样使用它:

<input
    ref=el => this.el = el
    defaultValue=this.props.str.name
    name="name"
    type="text"
    className="form-control"
/> 

现在使用这个ref 来访问这样的值:

this.el.value

【讨论】:

【参考方案2】:

您可以改为在 with spread 运算符中克隆整个属性值,然后重新修改或编辑该值,例如:

state = Counters: [id:1,value:1,id: 2,value: 2,id: 3,value: 3,id: 4,value: 4]
increment = (Counter) => 

        //This is where the state property value is cloned 

        const Counters = [...this.state.Counters];
        console.log(Counters);
        const index = Counters.indexOf(Counter)
        Counters[index].value++
        this.setState(
            Counters: this.state.Counters
        )

【讨论】:

以上是关于不要直接改变状态,在 React JS 中使用 setState() react/no-direct-mutation-state的主要内容,如果未能解决你的问题,请参考以下文章

setState():不要直接改变状态。使用 setState()

如何修复 不要直接改变状态。将 setState() 与数组一起使用?

状态改变时在 React JS 中实现过渡效果

在 React JS 中,啥时候应该使用存储与直接操作视图的状态?

React 组件中的state和setState

不使用突变直接改变 Vuex 状态