【问题标题】:Component not updating on Map (dictionary) state change using hooks组件未使用钩子更新 Map(字典)状态更改
【发布时间】:2019-03-22 18:59:44
【问题描述】:

我有一个子组件,它应该根据带有复选框的可见性过滤器显示名称。我使用字典来跟踪每个名称的检查状态。但是,当我更新字典时,孩子不会更新。

这里是一个例子:https://codesandbox.io/s/8k39xmxl52

这些是组件:

const App = () => {
  const [names, setNames] = useState(seedNames);
  const [hidden, setHidden] = useState(new Map());

  const handleHidden = e => {
    const name = e.target.name;
    const hidden = e.target.checked;

    setHidden(hidden.set(name, hidden));
  };

  return (
    <div className="App">
      <VisibilityFilter
        names={names}
        hidden={hidden}
        handleHidden={handleHidden}
      />
      <DisplayNames names={names} hidden={hidden} />
    </div>
  );
};

const VisibilityFilter = ({ names, hidden, handleHidden }) => {
  return (
    <div>
      {names.map(name => (
        <div key={name}>
          <input
            type="checkbox"
            name={name}
            checked={hidden.get(name)}
            onChange={handleHidden}
            defaultChecked
          />
          <span>{name}</span>
        </div>
      ))}
    </div>
  );
};


const DisplayNames = ({ names, hidden }) => {
  const visibleNames = names.filter(name => !hidden.get(name));

  return (
    <div>
      {visibleNames.map(name => (
        <div key={name}>{name}</div>
      ))}
    </div>
  );
};

【问题讨论】:

    标签: javascript reactjs dictionary react-hooks


    【解决方案1】:

    不可变状态的使用对于 React 来说是惯用的,预计会使用简单类型,如普通对象和数组。

    映射set 返回相同的映射,而useState 仅支持不可变状态。如果以相同的状态调用 setter 函数,则不会更新组件:

    setHidden(hidden.set(name, hidden))
    

    状态应该保持不变:

    setHidden(new Map(hidden.set(name, hidden)))
    

    这可能会引入一些开销,并无视 ES6 Map 可能带来的好处。除非Map 需要严格的项目顺序和非字符串键等功能,否则最好使用纯对象来实现相同目的。

    【讨论】:

    • 我对 Estus 的回答写了更详细的解释 - medium.com/swlh/…
    • 不错的文章。请注意,&lt;li key={k}&gt; 没有考虑非字符串键,这是使用映射而不是对象的重要且可能主要原因。
    猜你喜欢
    • 2022-07-11
    • 2019-12-23
    • 1970-01-01
    • 2021-05-19
    • 1970-01-01
    • 2021-06-15
    • 2017-05-05
    相关资源
    最近更新 更多