【问题标题】:React state is updating but the component is notReact 状态正在更新,但组件没有
【发布时间】:2021-08-26 09:20:31
【问题描述】:

有一个组件通过存储在状态中的数组进行映射。一个按钮,当它被点击时它会更新状态,这个动作是有效的。

问题是组件也没有更新。

代码如下:

const MyComponent = () => {
   ...
   const [fields, setFields] = useState([{value: 'test', editable: false},
                                         {value: 'test2', editable: false}]);

  ...

  const toggleClass = (id) => {
     const aux = fields;
     aux[id].editable = true;
     setFields(aux);
  }
  ...

  return (
     <div>
      ...
      {fields.map((field, id) => {
          return (
            <div>
              <input className={field.editable ? 'class1' : 'class2'} />
              <button onClick={() => toggleClass(id)}>click</button>
            </div>
          );
      })}
     </div>
  );

我把日志和状态 (fields) 在点击后更新为可编辑 = true。但是 css 类没有改​​变。

这个问题有解决办法吗?

【问题讨论】:

  • 你能检查状态是否正在更新。可以在useEffect中添加console.log
  • 复制fields,就像const aux = [...fields];一样。 React 需要不同的对象引用才能在非基元的情况下进行渲染。
  • 不要改变状态。

标签: javascript html reactjs ecmascript-6 state


【解决方案1】:

发生这种情况是因为您正在改变 fields 的值,这使得 React 无法确定是否更新组件。理想情况下,如果您应该向setFields 提供一个新对象。 因此,您的 toggleClass 函数应该如下所示:

const toggleClass = (id) => {
const aux = [...fields]; //This gives a new array as a copy of fields state
aux[id].editable = !aux[id].editable;
setFields(aux);

}

顺便说一句,我还注意到您没有为地图输出的每个 div 分配一个 key 道具。提供key 属性是一个很好的做法,最好不要使用索引作为键。

【讨论】:

    【解决方案2】:

    您需要复制现有状态数组,否则您会改变状态,这是一种不好的做法。

    const toggleClass = id => {
      const aux = [...fields]; //here we spread in order to take a copy
      aux[id].editable = true; //mutate the copy
      setFields(aux); //set the copy as the new state
    };
    

    【讨论】:

    • 另外,fields 继续指向同一个底层对象,这就是组件不会重新渲染的原因。
    猜你喜欢
    • 2019-03-10
    • 2020-01-16
    • 1970-01-01
    • 1970-01-01
    • 2019-09-29
    • 2018-05-15
    • 2021-03-25
    • 2018-09-25
    • 2019-04-29
    相关资源
    最近更新 更多