react 中使用了 useState 的 ui 组件的调用顺序

2021-05-13 15:02:58 +08:00
 Liyiw

react 对于 hooks 的调用顺序是有要求的,要求 hooks 的调用顺序要相同(不能在 if 语句中使用 useState ) ,才能保证 useState 获得正确的 state

但是文档里面只规定了 hooks 要按顺序(我理解的 hooks 是不返回 ui 的逻辑组件),却没有规定使用 useState 的 ui 组件的也要按顺序

那么,通过 if 语句进行条件渲染,渲染使用了 useState 的 ui 组件是否会导致 useState 得到的错误的 state ?

例如组件 Component,里面使用了 useState

const Component = (props) => {
    const [state] = useState(props.prop)
    console.log(state)
    return <h1>{state}</h1>
}

然后根据条件渲染两个这样的组件

function App() {
    const [state, setState] = useState(0)
    useEffect(
        () => {
            setTimeout(() => {
                setState(1)
            }, 1000)
        }
    )
    return (
        <div>
            {state === 0 ? <Component prop={[1, 2, 2, 3]}/> : null}
            <Component prop={'strange'}/>
        </div>
    );
}

这个代码的逻辑是:一开始渲染了两个 Component,1s 后 state 变为 1,第一个组件被移除,第二个组件 rerender

按照我的理解:useState 的数据在一个链表中,第一个 Component 没有被调用,链表的指针还是指向第一个 Component 的 state,那么第二个 Component 在 useState 的时候应该拿到的是第一个组件的 state

但结果是,第二个 Component 还是拿到了属于它的正确的 state,react 也没有报错,为什么呢?

我查了半天,Google 上全是说 hooks 的调用要按顺序,查不到使用了 useState 的 ui 组件要不要按顺序。如果确实可以不按顺序调用的话,react 是如何做到的?

学了一天多的 react,实在找不到这个问题的资料:((

1144 次点击
所在节点    问与答
6 条回复
huijiewei
2021-05-13 16:41:52 +08:00
运行没有问题啊
sgiyy
2021-05-13 16:47:12 +08:00
跟 UI 无关吧,每个组件的状态自己维护一套,包括 hooks
catcn
2021-05-14 00:48:48 +08:00
两个 Component 传进去的 prop 都是独立的的,什么链不链的
catcn
2021-05-14 00:53:22 +08:00
Function Component 创建的时候,你就当是一个函数调用,props 就是一堆参数就好啦。
另外,Component 不需要 state 修改的时候,直接用 props 就好了,就像这样子:
<code>
const Component = (props) => {
console.log(props.prop)
return <h1>{props.prop}</h1>
}
</code>
Liyiw
2021-05-14 13:10:54 +08:00
@catcn #4,谢谢,我知道,我只是想试验一下 react 是否允许 使用了 useState 的 ui 组件调用顺序不同,所以才用了 useState
Zenyk
2021-05-14 13:26:27 +08:00
每个组件内维护的所有 hooks 都是属于 virtual 树上该组件对应的节点的一个属性 也就是你提到的链表(而且是一个环形链表) 你这个例子父组件内的 state 属于父组件节点 两个 component 子组件是下一层的两个子节点 两者并无直接相关只是通过 props 传递了 state 下去 你说的 hooks 要按照顺序是指不能在条件判断语句内使用 setState

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/776724

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX