为什么第一个代码片段可以解决过时的闭包,而第二个代码片段却不能?

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

感觉第一张和第二张没什么区别。但第一个代码片段可以解决陈旧的闭包问题。那么,为什么第二个不能呢?我实在想不通。谁能从JavaScript闭包的原理来解释一下吗?

// ==========================  First code snippet ========================

let _formVal
export default function App() {
  const [formVal, setFormVal] = useState('');

_formVal =  formVal

  const handleSubmit = useCallback(() => {
    console.log('_formVal:', _formVal);
  }, []);

  return (
    <>
      <input
        onChange={(e) => {
          setFormVal(e.target.value);
        }}
        value={formVal}
      />
      <MemoziedSuperHeavyComponnent onSubmit={handleSubmit} />
    </>
  );
}

// ==========================  Second code snippet ========================

export default function App() {
  const [formVal, setFormVal] = useState('');

const _formVal =  formVal
  const handleSubmit = useCallback(() => {
    console.log('_formVal:', _formVal);
  }, []);

  return (
    <>
      <input
        onChange={(e) => {
          setFormVal(e.target.value);
        }}
        value={formVal}
      />
      <MemoziedSuperHeavyComponnent onSubmit={handleSubmit} />
    </>
  );
}
javascript reactjs closures
1个回答
0
投票

在第一个示例中,仅创建了一个

_formVal
变量,该变量位于顶部模块范围级别,因此这就是函数组件读取和更新的变量。

在第二个示例中,为组件的每个渲染创建多个

_formVal
变量,因为每次重新渲染都会再次调用您的
App
函数。由于您的
useCallback()
引用永远不会更新,并且始终是在初始渲染时创建的第一个函数(由于空依赖项
[]
),因此该函数将始终可以访问创建的第一个
_formVal
变量,而不是后续的变量未来的渲染。

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