p3rzival
p3rzival

Reputation: 33

Map props from redux to component state

I've been using React and Redux for the last 2 weeks and I'm not entirely sure of how everything works and after hours of searching about this and not really finding the information I needed I decided to ask 😅

I'm working on a webapp created with React and using redux to handle some things such as the authentication state. In this case, I'm using Google Authentication (passportjs + google plus api). I'm getting the user's info from my mongoDB and storing it in the state of the redux store. That works fine.

Then, from a specific component, I'm currently using:

function mapStateToProps({ auth }) {
    return { auth };
}

export default connect(mapStateToProps) (ExampleComponent);

This works just fine, the issue though, comes when I try to store this props in the component's state. I've tried setting the state on the component's constructor and it just sets things as null.

Apparently, and here is what I don't really understand, the props start by containing a null 'auth' field and then a second later, the auth gets filled with that mapStateToProps info.

If I call those props in the render method of the component, it works just fine, but if I want to store the value of this.props.auth in the component's state, it won't work.

Am I thinking about all this in a wrong way? Am I not understanding how the flow works or...? I don't get why the props start by beeing null and get modified later.

I've also tried to have a function that modifies the state with props values and to call that function from inside the render method of the component (which already contains the props) but it creates an infinite loop.

    setInitialStates() {
          this.setState({
                val1: this.props.auth.val1,
                val2: this.props.auth.val2,
                val3: this.props.auth.val3
          });
    }

.

render() {
        if(this.props.auth) {
            this.setInitialStates();
        }
        ...
    }

I've also tried calling this setState in ComponentDidMount, but it doesn't seem to do anything!

componentDidMount() {
        if(this.props.auth) {
            this.setState({
                val1: this.props.auth.val1,
                val2: this.props.auth.val2,
                val3: this.props.auth.val3
            });
        }
    }

Can someone with a better understanding of react and redux through some light on this please? Thanks!

Upvotes: 3

Views: 4498

Answers (3)

May'Habit
May'Habit

Reputation: 1372

I'm facing a problem like you and I realize that you can use componentWillReceiveProps or getDerivedStateFromProps but you need to trigger local state change to map new props. I try some case and I dont know when it auto change or not so I write this funtions to re-render whenever dispatch action:

setCount() {
    let {count} = this.state;
    this.setState({count: count++});
}

This is not best solution but this is the best way to do this easily.

Upvotes: 0

Andrii Starusiev
Andrii Starusiev

Reputation: 7764

componentDidMount fire once, after component is mounted. But redux send new props to your component every time redux state updated and your component use this state fields. componentWillReceiveProps will check every new props coming.

componentWillReceiveProps(nextProps) {
      this.setState({
            val1: nextProps.auth.val1,
            val2: nextProps.auth.val2,
            val3: nextProps.auth.val3
      });
}

Note

This lifecycle is deprecated now and is called UNSAFE_componentWillReceiveProps. Check the link below to see alternatives.

https://reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops

Upvotes: 2

Muthu Kumaran
Muthu Kumaran

Reputation: 56

componetDidMount will get invoked only when the component is mounted. so you have to use componentWillReceiveProps, which gets invoked on props changes.

For better understanding check this out: https://levelup.gitconnected.com/componentdidmakesense-react-lifecycle-explanation-393dcb19e459

Upvotes: 1

Related Questions