我的组件有两个Rect.useEffect
钩
const Example = ({ user }) => {
React.useEffect(() => {
autorun(() => {
console.log("inside autorun", user.count);
});
});
// Only runs once
React.useEffect(() => {
console.log("Why not me?");
});
return <Observer>{() => <h1>{user.count}</h1>}</Observer>;
};
我使用mobx
更新此组件。它被正确地重新渲染。但"Why not me?"
只打印一次。
默认情况下,效果在每次完成渲染后运行
这意味着console.log("Why not me?");
也应该在每次更新prop user
时运行。但事实并非如此。控制台输出就是这个
这种明显不一致背后的原因是什么?
我的完整代码可以在这里查看
在Mobx中,就像提供渲染函数回调的Observer
组件一样,autorun
函数也独立于反应生命周期执行。
出现这种情况是因为您将用户计数作为可观察变量。
根据mobx-react文档
Observer是一个React组件,它将observer应用于组件中的匿名区域。它需要一个单独的,无参数的函数,它应该只返回一个React组件。将跟踪函数中的渲染并在需要时自动重新渲染。
和mobx文档
当使用
autorun
时,提供的函数将始终立即触发一次,然后每次其依赖项之一发生更改时再次触发。
您可以通过直接在功能组件内部进行记录来确认此行为,并且您将观察到该组件仅呈现一次
编辑:
回答你的问题
如果我改变
useEffect
React.useEffect(autorun(() => {console.log("inside autorun", user.count)}));
基本上从
useEffect
中删除匿名函数并直接传递autorun,然后它只运行一次。为什么会这样?有什么不同?
不同的是,autorun
返回一个disposer function
,在运行时将处置autorun
并且不再执行它。
来自文档:
autorun的返回值是一个处理器函数,可用于在不再需要时处理自动运行。
现在发生的事情是,因为useEffect在运行时执行提供给它的回调,所以执行的回调是autorun返回的disposer
函数,它基本上取消了你的自动运行。
看起来您的组件不会重新渲染。 autorun
收到一个回调,可能会独立于渲染调用它。
Example
组件只有在其父级重新渲染或其道具发生变化时才会重新渲染。
使用此代码观察实际发生的情况:
const Example = ({ user }) => {
console.log('render');
React.useEffect(() => {
console.log('useEffect autorun');
autorun(() => {
console.log("inside autorun", user.count);
});
});
// Only runs once
React.useEffect(() => {
console.log("Why not me?");
});
return <Observer>{() => <h1>{user.count}</h1>}</Observer>;
};