最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Map properties to state in react-redux - Stack Overflow

programmeradmin2浏览0评论

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);

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);
Share Improve this question edited Apr 10, 2017 at 10:22 deathangel908 asked Mar 31, 2017 at 17:06 deathangel908deathangel908 9,69910 gold badges51 silver badges90 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 12

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 })
  }
}

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

Sure you can, onClick bind to some function like so:

onClick={this.myfunction.bind(this)}

Then define this myfuntion to be:

myfunction() {
    this.setState({ somestate: value });
    this.props.executeAction();
}

Here setState changes native component state, and calling action will change redux state if so defined by reducer. These states are independent.

Connect wrapper (first argument) maps state to props (redux state to react props) not component state itself.

Good question is why you need both, sure there are some examples where this could be useful...

In general if you need state that is needed globally then use redux state (easily applied to all components) and for some local states use react native state. (For example when you build some ui components like custom checkbox)

There's also static getDerivedStateFromProps:

static getDerivedStateFromProp(nextProps, prevState) {
  return {stateVar: nextProps.var} // this will propagate as component state
}
发布评论

评论列表(0)

  1. 暂无评论