Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
670 views
in Technique[技术] by (71.8m points)

redux - ReactJS: how to call useEffect hook only once to fetch API data

Using React, I have the following functional component where I make use of 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);

As you can see, I have an effect callback that calls the loadMessages() function in the useEffect() callback in my MessagingComponent:

  useEffect(() => {
    loadMessages();
  });

The call to loadMessages() loads messages which causes the component to re-render. This behaviour is as expected, however the problem is that the re-render causes the useEffect() hook to fire again, which causes loadMessages() to be called again. This in turn loads the messages from the back-end and causes the component to render again, and the cycle repeats.

How can I avoid this? Should I simply put an if condition in the useEffect() hook, and check for the messages property?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If I understand correctly, you want to mimic the "on component mounted" behaviour of regular class based react components via useEffect(), so that the effect callback only fires once on the first render.

To achieve that behaviour, you can pass an empty array to the second argument of useEffect() like so:

useEffect(() => {
  loadMessages();
}, []); /* <-- add this */

The second array argument allows you to specify which prop variables trigger the useEffect() callback (if any) when their value(s) change.

By passing an empty array, this means that useEffect() won't be triggered by any changes to input prop variables and will in turn only ever be called once, during the first render.

For more information on this second argument, see this documentation and this documentation


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...