简体   繁体   中英

How can I initialize Redux state for React component on its creation?

I have a route (using React-Router) with component which it renders. Every time this route opened and its component created I need to reset some part of Redux state (one reducer's state in fact), used in this component. This reducer is shared in some other parts of the app, so I use Redux state and not local component's state. So how can I reset the reducer's state every time my component created? I am wondering about best practice to do this.

  • I think if I'll dispatch actions in componentDidMount method, there will be blinking of previous state for some second.

  • Can I dispatch action to reset some reducer's state in component's constructor?

  • Is there any better approach? Can I somehow to set initial state in connect() function, so component will have resetted state each time it created? I check the docs, but I cannot find some argument for this.

Yes, you can dispatch action in constructor to change reducer state

constructor(prop){
    super(prop);
    prop.dispatch(action);
}

Another approach you can try is setting default props so that you don't need to call reducer(dispatch action)

ButtonComponent.defaultProps = {
  message: defaultValue,
};

One possible solution I can think of...

If you could go with the first approach, you can try to stop the previous state being shown while component is being re-rendered with reset state.

The only phase during which you would see the prevState is during the initial render. How about an instance variable to track the render count.

A rough draft.

import React from "react";
import { connect } from "react-redux";
import { add, reset } from "./actions";
class Topics extends React.Component {

  renderCount = 0;

  componentDidMount() {
    // Dispatch actions to reset the redux state
    // When the connected props change, component should re-render
    this.props.reset();
  }

  render() {
    this.renderCount++;
    if (this.renderCount > 1) {
      return (
        <div>
          {this.props.topics.map(topic => (
            <h3 id={topic}>{topic}</h3>
          ))}
        </div>
      );
    } else {
      return "Initializing"; // You can return even null
    }
  }
}

const mapStateToProps = state => ({ topics: state });
const mapDispatchToProps = (dispatch) => {
  return {

    add(value){
      dispatch(add(value));
    },
    reset(){
      dispatch(reset());
    }
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Topics);

Here renderCount is a class variable, that keeps incrementing on component render . Show a fallback UI on first render to avoid previous state from being shown and on second render (due to redux store update), you could display the store data.

A working example added below. I have added an approach to avoid the fallback UI as well. Have a look if it helps.

https://stackblitz.com/edit/react-router-starter-fwxgnl?file=components%2FTopics.js

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM