Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map properties to state in react-redux

I have a component that uses state to provide data to user. For example <div>this.state.variableInState</div>. This component can dispatch some method (for example on onClick action). I'm currently using react-redux an connect method to map store to props. Is there a way I can setState after dispatch?

// actions
export function executeAction() {
  return function (dispatch, getState) {
    dispatch({
      type: 'MY_ACTION',
      payload: axios.get('/some/url')
    });
  };
}
// reducer

export default function (state = {}, action) {
  switch (action.type) {
    case 'MY_ACTION_FULFILLED':
      return {...state, myVariable: action.payload.data}
  }
}
//component
class MyComponent extends Component {
  render() {
    (<div onClick={this.props.executeAction.bind(this)}>
      {this.state.variableInState}
      </div>)
  }

  someOtherMethod() {
    // I want to operate with state here, not with props
    // that's why my div gets state from this.state instead of this.props
    this.setState({variableInState: 'someValue'})
  }
}


export default connect((state, ownProperties) => {
  return {
    // So I want to change MyComponent.state.variableInState here
    // but this method updates MyComponent props only
    // What can I do?
    variableInProps: state.myVariable
  }
}, {executeAction})(MyComponent);
like image 210
deathangel908 Avatar asked Mar 31 '17 17:03

deathangel908


People also ask

What is mapStateToProps and mapDispatchToProps?

The mapStateToProps and mapDispatchToProps deals with your Redux store's state and dispatch , respectively. state and dispatch will be supplied to your mapStateToProps or mapDispatchToProps functions as the first argument.

What is ownProps in Redux?

ownProps (optional)​ You may define the function with a second argument, ownProps , if your component needs the data from its own props to retrieve data from the store. This argument will contain all of the props given to the wrapper component that was generated by connect . // Todo.js.


2 Answers

Whatever i understand, all you want to do is to convert the component's props to component's own state. You can always change the component's props to component's state in the componentWillReceiveProps life cycle method in component like this.

//component
class MyComponent extends Component {
  componentWillReceiveProps(newProps){
     if(newProps.variableInProps != this.props.variableInProps){
         this.setState({variableInState: newProps.variableInProps })
     }
  }
  render() {
    (<div onClick={this.props.executeAction.bind(this)}>
      {this.state.variableInState}
      </div>)
  }

  someOtherMethod() {
    // I want to operate with state here, not with props
    // that's why my div gets state from this.state instead of this.props
    this.setState({variableInState: 'someValue'})
  }
}


export default connect((state, ownProperties) => {
  return {
    // So I want to change MyComponent.state.variableInState here
    // but this method updates MyComponent props only
    // What can I do?
    variableInProps: state.myVariable
  }
}, {executeAction})(MyComponent);

componentWillReceiveProps method is always executed by react whenever a new props is coming to component so this is the right place to update your component's state according to your props.

UPDATE :

The componentWillReceiveProps has been deprecated. So instead of this method you can use componentDidUpdate method to do this. componentDidUpdate method takes previous props and previous state as arguments. So you can check for the change in props and then set the state.

componentDidUpdate(prevProps) {
  if(prevProps.variableInProps !== this.props.variableInProps){
    this.setState({variableInState: this.props.variableInProps })
  }
}
like image 68
Prakash Sharma Avatar answered Nov 15 '22 20:11

Prakash Sharma


I think you're not supposed to directly change the state like this. why not call another action to perform what you want?

The state should be immutable when using Redux. You should dispatch an action. A Reducer should receive the action and the current state, and return a new state object that includes the changes you want to make. Check this: http://redux.js.org/docs/introduction/ThreePrinciples.html#changes-are-made-with-pure-functions

like image 21
Moe Avatar answered Nov 15 '22 19:11

Moe