next.js 即使数据没有改变,组件是否会在每次进入页面时重新呈现?

rkkpypqq  于 2023-03-18  发布在  其他
关注(0)|答案(1)|浏览(207)

我不是很了解备忘录是如何和组件一起工作的。我有一个这样的组件。它很简单,而且是静态的。

const Home = memo((props: any) => {     
  useEffect(() => {
    console.log('home changed');
  }, [])   
  return (
    <>
    <h1>This is homepage</h1>
    </>
  )  
})

我的路由是/home,每次到首页路由,总是得到日志为home change的消息,那么这个组件没有缓存memo,如果缓存了,怎么实现这个组件不重新渲染呢?

eh57zj3b

eh57zj3b1#

memo不能停止挂载组件时发生的第一次渲染。该渲染必须始终发生。因此,如果您从主页路由离开,则会卸载它,当您返回时,必须重新挂载它,从而导致一次渲染
相反,memo所做的可能是跳过“later”(稍后)的渲染,每次组件由于属性的改变而重新渲染时,react都会先对所有属性进行一个粗略的比较,如果它们都没有改变,它就跳过渲染并使用组件上次返回的内容。
实际上,在大项目中我们有很多 prop ,每个 prop 里面都有很多功能。输入onChange总是改变 prop ,所以我们必须像这样为每个动作添加useMemo?
为了让memo正常工作, prop 需要保持不变,所以你需要确保你没有改变 prop 。函数确实是你需要小心的一种情况,因为如果你每次渲染都创建一个全新的函数,然后将其传递给一个子组件,子函数的记忆经常被破坏。通常的解决方法是将函数 Package 在useCallback中,以便在每个渲染中使用相同的函数示例。例如:

const Parent = () => {
  // This log will happen when mounting, plus every time the count state changes
  console.log('rendering parent');

  const [count, setCount] = useState(1);
  useEffect(() => {
    const id = setInterval(() => {
      setCount(prev => prev + 1);
    }, 1000);
    return () => { clearInterval(id); };
  }, []);
  
  // Without the useCallback, we would be making a new onChange with every render of
  //   Parent. With useCallback, we keep reusing the function from the first render
  const onChange = useCallback((event) => {
    // Do something
  }, []);  

  return (
    <div>
      Count: {count}
      <Child onChange={onChange} />
    </div>
}

const Child = memo(({ onChange }) => {
  // This log will only happen when mounting, plus when onChange changes. And thanks
  //   to useCallback, onChange will not change.
  console.log('rendering child');
  return (
    <input onChange={onChange}/>
  )
})

相关问题