【问题标题】:Reactjs hooks: update value of mapReactjs 钩子:更新地图的值
【发布时间】:2020-07-23 22:31:15
【问题描述】:

我是 reactjs 的新手,这就是为什么它对你来说很幼稚。

我需要更新其键未知的映射的值。

  const App = () => {
    const [storeMap, setStoreMap] = useState(new Map());
    let _tmpMap = new Map();
    return (<>
    {Object.keys({ key1: "hey", key2: "you" }).map((item) => {
          return (
            <button
              value={item}
              key={item}
              onClick={(e) => {
                _tmpMap.set(item, e.target.value);
           
                console.log(..._tmpMap); // {1}
                setStoreMap(_tmpMap);
              }}
            >
              {item}
            </button>
          );
          //   return <i key={item}>KJ </i>;
        })}
  </>)
   
  }

点击两个按钮后,我期望在上面的代码中看到的是:

  /*    {1}    */ 
  console.log(..._tmpMap)
  //i expect this: {key1:"key1" , key2:"key2"}

我实际看到的是按key 1后的{key1:"key1"}和按key 2后的{ key2:"key2"}

我的问题是:

如何在保留以前的条目的同时更新 storeMap?

Here is the code

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    Ciao,here 工作代码。如果单击key1key2 按钮,元素将添加到地图中,如果单击show result 按钮,您将看到storeMap 值。

    【讨论】:

      【解决方案2】:

      当您调用setStoreMap 时,组件会重新渲染,_tmpMap 会再次评估为新的 Map。您更新的地图属于之前的渲染,无法访问。您希望在渲染之间保留的任何内容都必须处于 state 或 ref 中,因此,您可以执行以下操作:

      const App = () => {
          const [storeMap, setStoreMap] = useState(new Map());
          let _tmpMap = useRef(new Map());
          return (<>
          {Object.keys({ key1: "hey", key2: "you" }).map((item) => {
                return (
                  <button
                    value={item}
                    key={item}
                    onClick={(e) => {
                      _tmpMap.current.set(item, e.target.value);
                      setStoreMap(new Map(_tmpMap.current));
                    }}
                  >
                    {item}
                  </button>
                );
                //   return <i key={item}>KJ </i>;
              })}
        </>)   
      }
      

      但是,通常建议不要将 Maps 与 React 一起使用,因为它们是可变的,并且 React 无法知道何时发生了变异。 storeMap 触发重新渲染和效果的唯一方法是每次更新时将其设置为新地图。如果你绝对必须使用 Maps,那么可变引用是 React 提供的最接近它们的东西。对象是属于 React 状态的最复杂的东西。 See this thread.

      【讨论】:

      • 我浏览了您提供的两个选项。但是,它并没有解决我的问题。当我使用 useRef 钩子时,它会更新 storeMap 一次,并且反应不会感知到其值的进一步变化。
      • 正确。正如我所说,地图是一种可变的数据存储,旨在在不丢失其参考价值的情况下进行更新。这与 React 决定何时更新状态变量的方式相反;通过比较浅不等式。我能想到的最好的解决方案是在每次更新时在状态中设置一个新的地图——我已经调整了我的答案。我再次质疑您为什么要这样做,因为您现在已经失去了使用地图的许多好处。
      • 我有一些我不知道的列表。每个列表都有一个键,我想将它们的选定值存储在地图上。说 selectMap = {list1: "option1", list2:"option2 ... }。每次用户在每个列表上选择一个项目时,我都想更新 selectMap。这就是我使用 Map 的原因。如果有更深刻的见解,请告诉我这样做的方法。
      【解决方案3】:

      storeMap.set() 更新地图,setStoreMap 设置状态。

      React 比较新旧 Map 的引用,在这种情况下,它们共享相同的值。 如果你想让 React “知道”更新,你需要将 Map 的克隆而不是旧引用的副本传递给 setStoreMap,你可以通过创建一个新的 Map 来做到这一点。 我相信你可以放弃使用_tmpMap

      const App = () => {
          const [storeMap, setStoreMap] = useState(new Map());
      
          const updateStoreMap = (k, v) => {
              // pass a clone of storeMap
              setStoreMap(new Map(storeMap.set(k, v)));
          };
          
          return (
              <>
                  {Object.keys({ key1: 'hey', key2: 'you' }).map((item) => {
                      return (
                          <button
                              value={item}
                              key={item}
                              onClick={(e) => {
                                  updateStoreMap(item, e.target.value);
                              }}
                          >
                              {item}
                          </button>
                      );
                      //   return <i key={item}>KJ </i>;
                  })}
              </>
          );
      };
      

      【讨论】:

        猜你喜欢
        • 2022-06-22
        • 1970-01-01
        • 2019-11-21
        • 1970-01-01
        • 1970-01-01
        • 2019-09-13
        • 1970-01-01
        • 2014-03-01
        • 2021-06-06
        相关资源
        最近更新 更多