【问题标题】:React w/hooks: prevent re-rendering component with a function as propReact w/hooks:防止使用作为 prop 的函数重新渲染组件
【发布时间】:2019-07-06 17:18:18
【问题描述】:

假设我有:

const AddItemButton = React.memo(({ onClick }) => {
  // Goal is to make sure this gets printed only once
  console.error('Button Rendered!');
  return <button onClick={onClick}>Add Item</button>;
});

const App = () => {
  const [items, setItems] = useState([]);

  const addItem = () => {
    setItems(items.concat(Math.random()));
  }

  return (
    <div>
      <AddItemButton onClick={addItem} />
      <ul>
        {items.map(item => <li key={item}>{item}</li>)}
      </ul>
    </div>
  );
};

每当我添加一个项目时,&lt;AddItemButton /&gt; 都会重新渲染,因为 addItem 是一个新实例。我尝试记忆 addItem:

 const addItemMemoized = React.memo(() => addItem, [setItems])

但这是重用第一次渲染中的 setItems,而

 const addItemMemoized = React.memo(() => addItem, [items])

自从items 参考更改后不再记忆。

我可以的

 const addItem = () => {
   items.push(Math.random());
   setItems(items);
 }

因为这不会改变 items 的引用并且没有任何更新。

一种奇怪的方法是:

  const [, frobState] = useState();
  const addItemMemoized = useMemo(() => () => {
    items.push(Math.random());
    frobState(Symbol())
  }, [items]);

但我想知道是否有更好的方法不需要额外的状态引用。

【问题讨论】:

    标签: javascript reactjs react-hooks


    【解决方案1】:

    当前首选路线是useCallback,与您的useMemo 解决方案相同,但未来可能会进行其他优化。传递一个空数组 [] 以确保函数在组件的生命周期内始终具有相同的引用。

    在这里,您还想使用functional state update form,以确保始终根据当前状态添加项目。

      const addItem = useCallback(() => {
        setItems(items => [...items, Math.random()]);
      }, []);
    

    【讨论】:

    • “useCallback(fn, inputs) 等价于 useMemo(() => fn, inputs)。”这就是我所做的。但是由于项目引用由于传播/连接而发生变化,它不会被记忆
    • 好吧,在这里,您可以将[items] 更改为[],它仍然可以工作,因为更新取决于之前的状态。我将编辑我的答案。
    • 我认为这里的关键是在setItems中使用一个函数!谢谢@kingdaro
    • 是的,可以的 :P 当然可以
    猜你喜欢
    • 1970-01-01
    • 2019-05-29
    • 2019-07-28
    • 2023-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-07
    • 2020-02-05
    相关资源
    最近更新 更多