reactjs 使用useMemo在渲染期间更新React挂接状态

flvtvl50  于 2022-11-29  发布在  React
关注(0)|答案(3)|浏览(163)

useMemo可以 * 仅仅 * 用于在渲染期间 * 设置状态时避免额外的引用相等性检查代码/变量吗?
示例:useMemo在渲染期间带有setState,摘自此罕见的记录用例:

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}`;
}

上面大大减少了代码和额外的变量,否则只用于相等性检查,那么为什么文档暗示引用相等性检查应该手动完成?

dbf7pr2w

dbf7pr2w1#

这似乎是一个优雅的方式来减少锅炉板对我来说。我创建了一个代码和框来验证它的行为。

const UnitUnderTest = ({prop}) => {
  let [someState, setSomeState] = useState(false);

  const lessCodeThanCheckingPrevRow = useMemo(
    () => setSomeState(current => !current), 
    [prop],
  );

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

  console.log('run component');

  return `State: ${someState}`;
}

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

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

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

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

> run component 
> run component 
> update finished

正如您所看到的,在更新周期完成之前,组件已经运行了两次。这相当于getDerivedStateFromProps的行为。
我想没有更深层次的思考为什么文件提出了一个稍微不同的技术。在某种程度上,这是一个手动检查,但在一个整洁的方式。+1的想法。

yptwkmov

yptwkmov2#

使用useEffect挂接实现此行为。useMemo用于存储一个值,该值在每次呈现时不一定会更改,这样可以避免对该值进行无用的重新计算

cwtwac6a

cwtwac6a3#

如果问题是每个用户操作(在本例中是滚动)都有一个值发生变化,那么useMemo不是最好的选择。也许useCallback是一个更好的选择。代码块将与上面定义的代码块相同,但不是useMemo,而是useCallback,并在依赖关系数组中包含状态。

相关问题