使用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);
如您所见,我有一个效果回调,它在loadMessages()
的{{1}}回调中调用useEffect()
函数:
MessagingComponent
对 useEffect(() => {
loadMessages();
});
的调用会加载消息,从而导致组件重新呈现。此行为是预期的,但是问题在于重新渲染会导致loadMessages()
挂钩再次触发,从而导致useEffect()
被再次调用。反过来,这会从后端加载消息,并使组件再次呈现,并且循环重复进行。
如何避免这种情况?我是否应该在loadMessages()
挂钩中放入if条件,并检查messages属性?
答案 0 :(得分:2)
如果我的理解正确,您想通过useEffect()
模仿基于常规类的常规组件的“在组件上安装”的行为,以使效果回调仅在第一个渲染上触发一次。
要实现该行为,可以将空数组传递给useEffect()
的第二个参数,如下所示:
useEffect(() => {
loadMessages();
}, []); /* <-- add this */
第二个数组参数允许您指定当变量的值更改时,哪些prop
变量会触发userEffect()
回调(如果有)。
通过传递一个空数组,这意味着useEffect()
不会被输入prop
输入变量的任何更改所触发,并且在第一个渲染期间只会被调用一次。 >
答案 1 :(得分:0)
useEffect()
是功能组件的反应挂钩,涵盖了类组件的生命周期挂钩的功能。 useEffect()
组合了类组件的componentDidMount(), componentDidUpdate()
和componentWillUnmount()
,这意味着它将在安装组件时,组件状态改变时以及从DOM卸载组件时执行。
检查以下示例,
useEffect(() => {
setTimeout(() => {
alert("data saved");
}, 1000);
});
当组件被安装/初始渲染,组件的状态改变以及从DOM卸载组件时,将执行以上代码/警告。
为使上述代码运行更少,我们可以将值的数组作为第二个参数传递,作为该效果的依赖项。如果其中一项依赖项发生更改,效果将再次运行。
考虑到我们将人员数组传递到功能组件的props中,我们希望仅在人员数组更改时执行警报。
useEffect(() => {
setTimeout(() => {
alert("data saved");
}, 1000);
}, [props.persons]);
这将在初始渲染期间和props.persons
更改时执行代码。
因此,仅在初始渲染/组件安装期间执行代码,您可以传递一个空数组,这意味着在效果应执行时未指定任何依赖项。因此,在初始渲染期间和卸载组件时运行。
useEffect(() => {
setTimeout(() => {
alert("data saved");
}, 1000);
}, []);
您可以按如下所示修改useEffect()
钩子,使其仅调用一次即可获取API数据,
useEffect(() => {
loadMessages();
}, []);