当从 props 更新状态时,为什么 useEffect() 而不是直接在组件中检查?

Mic*_*dis 2 reactjs

当 props 改变时更新状态时,常用 方法useEffect()是将 props 作为依赖项使用:

const Component = ({prop}) => {
  const [state, setState] = useState(prop);

  useEffect(() => {
    setState(prop);
  }, [prop]);

  return <div>{state}</div>;
}
Run Code Online (Sandbox Code Playgroud)

我想知道,与直接在组件本身中进行比较相比,这是否有优势,如下所示:

const Component = ({prop}) => {
  const [state, setState] = useState(prop);

  if (prop !== state) {
    setState(prop);
  }

  return <div>{state}</div>;
}
Run Code Online (Sandbox Code Playgroud)

看起来这两种方法都会导致组件执行两次——一次 prop 和状态不同步,一次同步——但第二种方法看起来避免了向堆栈添加钩子。它看起来也可以在 DOM 协调之外进行优化,因为它不必像 useEffect() 那样等待 DOM 生成。我什至不确定它是否比“The Hooks Way”更容易阅读。

有谁知道为什么 useEffect() 路线比内联检查更好?

sat*_*164 5

React 官方文档使用第二种方法来同步 props 来声明:

https://reactjs.org/docs/hooks-faq.html#how-do-i-implement-getdrivenstatefromprops

function ScrollView({row}) {
  const [isScrollingDown, setIsScrollingDown] = useState(false);
  const [prevRow, setPrevRow] = useState(null);

  if (row !== prevRow) {
    // Row changed since last render. Update isScrollingDown.
    setIsScrollingDown(prevRow !== null && row > prevRow);
    setPrevRow(row);
  }

  return `Scrolling down: ${isScrollingDown}`;
}
Run Code Online (Sandbox Code Playgroud)

在渲染期间更新状态和在渲染期间更新状态之间的区别useEffect在于,在useEffectReact 已经提交更新之后调用,即更新将反映在 DOM 中,然后您将更新状态,这将再次更新 DOM。第二种方式会导致重新渲染,但只有一次对 DOM 的提交。