Rin*_*ala 7 reactjs react-hooks
我正在阅读 React-hooks 概念。我经历了一条规则,上面写着Don't call React hooks inside conditions。他们在这里提供了解释链接。
function Form() {
// 1. Use the name state variable
const [name, setName] = useState('Mary');
// 2. Use an effect for persisting the form
useEffect(function persistForm() {
localStorage.setItem('formData', name);
});
// 3. Use the surname state variable
const [surname, setSurname] = useState('Poppins');
// 4. Use an effect for updating the title
useEffect(function updateTitle() {
document.title = name + ' ' + surname;
});
// ...
}
Run Code Online (Sandbox Code Playgroud)
我明白他们想说什么,但我无法得到确切的原因,比如为什么我不能在 if-else 块中使用 useEffect ?
还有一种说法
So how does React know which state corresponds to which useState call?
useState 每次的调用都是不同的,每次都会返回新的“[state, setState]”,那么知道谁调用了哪个 useState 有什么困难呢?
这与谁调用了哪个钩子无关useXXXX(即useState、useEffect等)。它是关于钩子如何在内部实现以及如何与每个组件关联的。React 还有很多其他问题的解决依赖于钩子的调用顺序。
来自文档Hooks FAQ 部分
\n\n\nReact 如何将 Hook 调用与组件关联起来?
\n有一个与每个组件关联的 \xe2\x80\x9c 内存单元\xe2\x80\x9d 的内部列表。它们\xe2\x80\x99只是JavaScript对象,我们可以在其中放置一些数据。当您调用像 useState() 这样的 Hook 时,它会读取当前单元格(或在第一次渲染期间初始化它),然后将指针移动到下一个单元格。这就是多个 useState() 调用每个获得独立本地状态的方式。
\n
内部钩子的实现类似于队列,其中每个钩子代表一个引用下一个钩子的节点。内部结构可能看起来与此类似,
\n{\n memoizedState: \'a\',\n next: {\n memoizedState: \'b\',\n next: null\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n以调用 4 次有 4 个状态变量为例useState。对于每个钩子调用,如果该值尚未初始化(即在第一次渲染时),它将初始化从内存单元读取的值,然后在内部移动到下一个钩子。
// 4 independent local state variables with their own "memory cell"\n// nothing is called conditionally so the call order remains the same\n// across renders\nuseState(1) // 1st call \nuseState(2) // 2nd call\nuseState(3) // 3rd call\nuseState(4) // 4th call\nRun Code Online (Sandbox Code Playgroud)\nuseState(1)\n\nif (condition) { // if condition false hook call will be skipped\n useState(2) \n}\n\nuseState(3) \nuseState(4) \nRun Code Online (Sandbox Code Playgroud)\n现在,当您有条件地调用钩子时,如果条件是false钩子调用将被跳过。这意味着每个后续的钩子调用都会在调用顺序中移动 1,从而导致无法读取状态值或替换效果或更多难以检测的错误。
所以一般来说,有条件地调用任何钩子都是一个坏主意。仅在顶层调用钩子(而不是内部条件、嵌套函数或循环),这将有助于 React 为多个钩子调用保留钩子的状态。
\n基本上,挂钩依赖于调用索引。React 不知道给定useState()返回了什么,因为它是前一个渲染的状态,但它确实知道useState()该组件的第一次调用返回了 a[1,2]作为它的值,第二次调用返回了false。现在,如果 React 唯一知道的是给定调用索引的给定返回是什么,那么如果我可以编写这样的组件,您认为会发生什么:
const [a, setA] = React.useState([1,2,3]);
let c;
if(a === [3,2,1]){
c = React.useState('X');
}
const [b, setB] = React.useState(false);
React.useEffect(() => setA([3,2,1]), []);
Run Code Online (Sandbox Code Playgroud)
现在,react 从第一个渲染中知道第一个调用返回 [1,2,3] 而第二个返回 false。然后效果重新渲染组件,现在它不是第一次渲染,因此第一次调用将返回[3,2,1]更新后的状态,第二次调用(第一个c = ...)将返回 false,但随后 React 看到第三次调用,它应该返回什么?
从 React 的角度来看,这是没有意义的,从你的角度来看,这可能会导致大量的错误和问题。
当然,我的基本解释和 React 的解释都不是很多,这就是为什么有来源的原因,Dan Abramov,一位在 React 工作的人,在他的博客上有一篇关于这个的非常长而详细的文章,你可以在这里找到它。他还发布了很多有关 React 在幕后如何工作的其他内容,值得一读。
| 归档时间: |
|
| 查看次数: |
11725 次 |
| 最近记录: |