如何解决对 RecoilRoot
我有这些组件,没有任何后坐钩。
const C = () => {
console.log('---->C')
return <Text>C</Text>
}
const B = () => {
console.log('--->B')
return <>
<Text>B</Text>
<C/>
</>
}
const A = () => {
console.log('-->A')
return <>
<Text>A</Text>
<B/>
</>
}
const App = () => {
console.log('->App')
return (
<RecoilRoot>
<A />
</RecoilRoot>
);
};
当我在控制台中运行应用程序时会显示特定的日志:
LOG ->App
LOG -->A
LOG --->B
LOG ---->C
现在我要使用反冲钩来改变和访问原子状态
import { atom,useSetRecoilState,useRecoilState,useRecoilValue,RecoilRoot } from "recoil";
const atomTest = atom({
key: "abcatomTest",default: "A"
})
const C = () => {
console.log('---->C')
const [value,set] = useRecoilState(atomTest)
return <>
<Text>C</Text>
</>
}
const B = () => {
console.log('--->B')
const set = useSetRecoilState(atomTest)
return <>
<Text>B</Text>
<C/>
</>
}
const A = () => {
console.log('-->A')
const value = useRecoilValue(atomTest)
return <>
<Text>A</Text>
<B/>
</>
}
const App = () => {
console.log('->App')
return (
<RecoilRoot>
<A />
</RecoilRoot>
);
};
我什至不使用从 useRecoilValue
、useSetRecoilState
、useRecoilState
返回的值和函数,如果我使用它,它可以正常工作,但是在第一次渲染时,日志是:
LOG ->App
LOG -->A
LOG -->A
LOG ->App
LOG --->B
LOG ---->C
LOG ---->C
LOG --->B
LOG -->A
LOG ->App
LOG -->A
LOG --->B
LOG ---->C
为什么反冲会强制重新渲染包括 root 在内的多个组件,我根本不会改变状态,而且在 App 组件中也不依赖于任何状态!
解决方法
首先:React 执行一个函数并不意味着组件实际上重新渲染。 React 有提交和渲染阶段。在提交阶段,React 经历更改并调用子组件,检查是否有任何新内容要渲染。在渲染阶段,React 检查是否有组件需要重新渲染。如果输出、钩子状态和道具相同,则不会重新渲染,即使 React 之前调用了您的函数组件。这就是您看到所有日志的原因。您不是在检查重新渲染,而是检查函数执行。
您的 App 组件实际上依赖于状态,因为它呈现 RecoilRoot
组件。当那个组件发生变化时,React 会再次进入提交阶段并遍历所有子组件,看看是否有变化。
由于每个组件都使用引用 atomTest
原子的钩子,因此 Recoil 必须为该组件订阅该原子。所以 Recoil 和 React 必须通过树来寻找变化。
如果您检查 React Developer Tools 的 Profiler,您会发现没有实际的重新渲染,因为您的组件没有更改任何输出。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。