ReactJS:如何仅调用一次 useEffect 钩子来获取 API 数据
ReactJS: how to call useEffect hook only once to fetch API data
使用 React,我有以下使用 useEffect()
的功能组件:
import React, { useEffect } from 'react';
import { connect } from 'react-redux';
const MessagingComponent = React.memo(({ loadMessages, messages, ...props }) => {
useEffect(() => {
loadMessages();
});
return <div {...props}>These are the messages</div>;
});
const mapDispatchToProps = dispatch => ({
loadMessages: () => dispatch({ type: 'LOAD_MESSAGES' })
});
const mapStateToProps = state => {
return {
messages: state.chatt.messages.chatMessages
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(MessagingComponent);
如您所见,我在 MessagingComponent
:
的 useEffect()
回调中有一个调用 loadMessages()
函数的效果回调
useEffect(() => {
loadMessages();
});
对 loadMessages()
的调用会加载导致组件重新呈现的消息。此行为符合预期,但问题是重新呈现会导致 useEffect()
挂钩再次触发,从而导致 loadMessages()
再次被调用。这反过来从后端加载消息并导致组件再次呈现,然后循环重复。
我怎样才能避免这种情况?我应该简单地在 useEffect()
挂钩中放置一个 if 条件,然后检查消息 属性?
如果我理解正确,您想通过 useEffect()
模仿基于 class 的常规 React 组件的“组件安装”行为,以便效果回调仅在第一次渲染时触发一次.
要实现该行为,您可以将一个空数组传递给 useEffect()
的第二个参数,如下所示:
useEffect(() => {
loadMessages();
}, []); /* <-- add this */
第二个数组参数允许您指定哪些 prop
变量在其值更改时触发 useEffect()
回调(如果有)。
通过传递一个空数组,这意味着 useEffect()
不会被输入 prop
变量的任何更改触发,并且只会在第一次渲染期间被调用一次。
有关第二个参数的更多信息,see this documentation and this documentation
useEffect()
是功能组件的反应钩子,涵盖了 class 组件的生命周期钩子的功能。 useEffect()
结合了class组件的componentDidMount(), componentDidUpdate()
和componentWillUnmount()
,也就是说在组件挂载时、组件状态改变时、组件卸载时执行来自 DOM.
检查下面的例子,
useEffect(() => {
setTimeout(() => {
alert("data saved");
}, 1000);
});
上面的 code/alert 在组件 mounted/initial 渲染时执行,当组件状态改变时以及当组件从 DOM.
中卸载时
为了使上面的代码 运行 不那么频繁,我们可以传递一个值数组作为第二个参数,作为该效果的依赖项。如果依赖项之一发生更改,效果将再次 运行。
假设我们将人员数组传递到功能组件的道具中,我们希望仅当人员数组发生变化时才执行警报。
useEffect(() => {
setTimeout(() => {
alert("data saved");
}, 1000);
}, [props.persons]);
这将在初始渲染期间和 props.persons
更改时执行代码。
因此,要仅在初始 render/component 挂载期间执行代码,您可以传递一个空数组,这意味着在执行效果时没有指定依赖项。因此 运行 在初始渲染期间和卸载组件时。
useEffect(() => {
setTimeout(() => {
alert("data saved");
}, 1000);
}, []);
您可以如下修改 useEffect()
挂钩,使其仅调用一次以获取 API 数据,
useEffect(() => {
loadMessages();
}, []);
使用 React,我有以下使用 useEffect()
的功能组件:
import React, { useEffect } from 'react';
import { connect } from 'react-redux';
const MessagingComponent = React.memo(({ loadMessages, messages, ...props }) => {
useEffect(() => {
loadMessages();
});
return <div {...props}>These are the messages</div>;
});
const mapDispatchToProps = dispatch => ({
loadMessages: () => dispatch({ type: 'LOAD_MESSAGES' })
});
const mapStateToProps = state => {
return {
messages: state.chatt.messages.chatMessages
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(MessagingComponent);
如您所见,我在 MessagingComponent
:
useEffect()
回调中有一个调用 loadMessages()
函数的效果回调
useEffect(() => {
loadMessages();
});
对 loadMessages()
的调用会加载导致组件重新呈现的消息。此行为符合预期,但问题是重新呈现会导致 useEffect()
挂钩再次触发,从而导致 loadMessages()
再次被调用。这反过来从后端加载消息并导致组件再次呈现,然后循环重复。
我怎样才能避免这种情况?我应该简单地在 useEffect()
挂钩中放置一个 if 条件,然后检查消息 属性?
如果我理解正确,您想通过 useEffect()
模仿基于 class 的常规 React 组件的“组件安装”行为,以便效果回调仅在第一次渲染时触发一次.
要实现该行为,您可以将一个空数组传递给 useEffect()
的第二个参数,如下所示:
useEffect(() => {
loadMessages();
}, []); /* <-- add this */
第二个数组参数允许您指定哪些 prop
变量在其值更改时触发 useEffect()
回调(如果有)。
通过传递一个空数组,这意味着 useEffect()
不会被输入 prop
变量的任何更改触发,并且只会在第一次渲染期间被调用一次。
有关第二个参数的更多信息,see this documentation and this documentation
useEffect()
是功能组件的反应钩子,涵盖了 class 组件的生命周期钩子的功能。 useEffect()
结合了class组件的componentDidMount(), componentDidUpdate()
和componentWillUnmount()
,也就是说在组件挂载时、组件状态改变时、组件卸载时执行来自 DOM.
检查下面的例子,
useEffect(() => {
setTimeout(() => {
alert("data saved");
}, 1000);
});
上面的 code/alert 在组件 mounted/initial 渲染时执行,当组件状态改变时以及当组件从 DOM.
中卸载时为了使上面的代码 运行 不那么频繁,我们可以传递一个值数组作为第二个参数,作为该效果的依赖项。如果依赖项之一发生更改,效果将再次 运行。
假设我们将人员数组传递到功能组件的道具中,我们希望仅当人员数组发生变化时才执行警报。
useEffect(() => {
setTimeout(() => {
alert("data saved");
}, 1000);
}, [props.persons]);
这将在初始渲染期间和 props.persons
更改时执行代码。
因此,要仅在初始 render/component 挂载期间执行代码,您可以传递一个空数组,这意味着在执行效果时没有指定依赖项。因此 运行 在初始渲染期间和卸载组件时。
useEffect(() => {
setTimeout(() => {
alert("data saved");
}, 1000);
}, []);
您可以如下修改 useEffect()
挂钩,使其仅调用一次以获取 API 数据,
useEffect(() => {
loadMessages();
}, []);