使用useMemo在渲染期间更新React Hooks状态

问题描述 投票:1回答:2

可以将useMemo用于just以避免在设置状态期间渲染器时使用额外的参照相等性检查代码/变量吗?

示例:useMemosetState在从此rare documented use case进行的渲染期间:

function ScrollView({row}) {
  let [isScrolling, setIsScrolling] = useState(false);

  const lessCodeThanCheckingPrevRow = useMemo(
    () => {
      // Row changed since last render. Update isScrolling.
      setIsScrolling(true); // let's assume the simplest case where prevState isn't needed here
    },
    [row]
  );

  return `Scrolling down: ${isScrolling}`;
}

上面大大减少了代码和额外的var,仅将其用于相等性检查,所以为什么文档暗示必须手动进行引用相等性检查?

reactjs render react-hooks memoization
2个回答
0
投票

为此行为使用useEffect挂钩。 useMemo用于存储一个值,该值可能不必在每个渲染器上都发生变化,从而避免对该值进行无用的重新计算]


0
投票

这似乎是减少我的锅炉板的一种优雅方法。我创建了一个codeandbox来验证其行为。

const App = () => {
  const [prop, setProp] = useState(false);
  const handleClick = () => setProp(current => !current);

  return (
    <div>
      <button onClick={handleClick} >change prop</button>
      <UnitUnderTest prop={prop} />
    </div>
  )
};

function UnitUnderTest({prop}) {
  let [isScrolling, setIsScrolling] = useState(false);

  const lessCodeThanCheckingPrevRow = useMemo(
    () => {
      // Row changed since last render. Update isScrolling.
      setIsScrolling(true); // let's assume the simplest case where prevState isn't needed here
    },
    [prop]
  );

  useEffect(() => console.log('update finished'), [prop])

  console.log('run component');

  return `Scrolling down: ${isScrolling}`;
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Edit recursing-hopper-4ynjm

单击按钮以更改传递给组件的道具时输出:

> run component 
> run component 
> update finished 

您可以看到该组件在更新周期完成之前已经运行了两次。这等效于getDerivedStateFromProps的行为。

我想,为什么文档提出了稍微不同的技术,对此我们没有更深入的思考。从某种意义上说,这也是一种手动检查,但是很简洁。

© www.soinside.com 2019 - 2024. All rights reserved.