为什么 useEffect 不会在每次渲染时都触发?
Why useEffect doesn't fire on every render?
我的组件有两个 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?"
只打印一次。
By default, effects run after every completed render
这意味着每次 user
更新时 console.log("Why not me?");
也应该 运行。但事实并非如此。控制台输出是这样的
这种明显的不一致背后的原因是什么?
我的完整代码可以在这里查看
您的组件似乎没有重新呈现。 autorun
收到回调并可能独立于渲染调用它。
Example
组件仅在其父级重新渲染或其 props 更改时才重新渲染。
使用这段代码观察到底发生了什么:
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>;
};
在 Mobx 中,就像 Observer
提供渲染函数回调的组件一样,autorun
函数也是独立于 React 生命周期执行的。
发生此行为是因为您将 用户计数作为可观察变量。
根据 mobx-react 文档
Observer is a React component, which applies observer to an anonymous
region in your component. It takes as children a single, argumentless
function which should return exactly one React component. The
rendering in the function will be tracked and automatically
re-rendered when needed.
和 mobx 文档
When autorun
is used, the provided function will always be triggered
once immediately and then again each time one of its dependencies
changes.
您可以通过直接在功能组件中登录来确认此行为,您将观察到该组件仅呈现一次
编辑:
回答你的问题
If I change useEffect
to this
React.useEffect(autorun(() => {console.log("inside autorun", user.count)}));
basically remove anonymous function from useEffect
and just pass
autorun directly, then it is run only once. Why is it so? What's the
difference?
不同之处在于 autorun
returns 一个 disposer function
当 运行 将处理掉 autorun
并且不再执行它。
来自文档:
The return value from autorun is a disposer function, which can be
used to dispose of the autorun when you no longer need it.
现在发生的事情是,由于 useEffect 在 运行s 时执行提供给它的回调,执行的回调是 auto运行 返回的 disposer
函数,这实际上取消了你的自动运行.
我的组件有两个 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?"
只打印一次。
By default, effects run after every completed render
这意味着每次 user
更新时 console.log("Why not me?");
也应该 运行。但事实并非如此。控制台输出是这样的
这种明显的不一致背后的原因是什么?
我的完整代码可以在这里查看
您的组件似乎没有重新呈现。 autorun
收到回调并可能独立于渲染调用它。
Example
组件仅在其父级重新渲染或其 props 更改时才重新渲染。
使用这段代码观察到底发生了什么:
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>;
};
在 Mobx 中,就像 Observer
提供渲染函数回调的组件一样,autorun
函数也是独立于 React 生命周期执行的。
发生此行为是因为您将 用户计数作为可观察变量。
根据 mobx-react 文档
Observer is a React component, which applies observer to an anonymous region in your component. It takes as children a single, argumentless function which should return exactly one React component. The rendering in the function will be tracked and automatically re-rendered when needed.
和 mobx 文档
When
autorun
is used, the provided function will always be triggered once immediately and then again each time one of its dependencies changes.
您可以通过直接在功能组件中登录来确认此行为,您将观察到该组件仅呈现一次
编辑:
回答你的问题
If I change
useEffect
to thisReact.useEffect(autorun(() => {console.log("inside autorun", user.count)}));
basically remove anonymous function from
useEffect
and just pass autorun directly, then it is run only once. Why is it so? What's the difference?
不同之处在于 autorun
returns 一个 disposer function
当 运行 将处理掉 autorun
并且不再执行它。
来自文档:
The return value from autorun is a disposer function, which can be used to dispose of the autorun when you no longer need it.
现在发生的事情是,由于 useEffect 在 运行s 时执行提供给它的回调,执行的回调是 auto运行 返回的 disposer
函数,这实际上取消了你的自动运行.