react / redux:立即更新道具后,从州获取最新道具值

时间:2016-06-07 16:28:09

标签: reactjs redux

我遇到在使用调度问题更新道具后从状态映射的同步道具。

在JSX中,当我更改选择下拉列表时,然后触发handleChange方法。在handleChange中,它执行selectLayoutAction操作,调度操作,更新状态的selectLayout属性,之后我需要在下一行中使用更新的selectLayout属性来更新组件状态,但是我无法获得新的selectLayout值,我将获得旧的selectLayout ...如何获得由调度操作更新的最新selectLayout值?

https://gist.github.com/sevenLee/7d229a9e5d8e82b1d5e12040f3ae2ee8

handleChange(event) {
    event.preventDefault();
    this.props.selectLayoutAction(event.target.value); // update select layout

    this.setState({selectedLayoutOption: event.target.value});

    // I need the newest selectLayout value immediately, but when I only got the old selectLayout value
    // For example: select from layout1 to layout2, I can not get layout2, I got layout1
    this.setState({selectedThemeOption: this.getCurrentTheme(this.props.selectLayout)}); //<--- I can't use this
    this.setState({selectedThemeOption: this.getCurrentTheme(event.target.value)}); //<--- Finally, I replace with  'event.target.value'  for getting the latest value after selectting

    this.props.resetStyles();
 }

render() {
    const { layouts, selectLayout } = this.props;
    let layoutJS = [];

    if (layouts && layouts.toJS) {
      layoutJS = layouts.toJS();
    }

    return (
      <div>
        <select onChange={this.handleChange.bind(this)} value={this.state.selectedLayoutOption}>
          {this.renderOptions(layoutJS)}
        </select>
      </div>
    );
  }

function mapStateToProps(state) {
  console.log('Update selectLayout!!! ', state.selectLayout);   
  //When I dispatch action, I can get update selectLayout value right away here, but it can't map the state to props right away.
  return {
    layouts: state.layouts,
    selectLayout: state.selectLayout
  };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({ selectLayoutAction, setLayoutThemeAction, resetStyles }, dispatch);
}

2 个答案:

答案 0 :(得分:3)

这将假设来自redux的同步行为。永远不要假设任何关于setState和使用redux调度执行顺序。 所以,你可能想要的是要么做全面的redux并将所有内容放在redux的商店中,然后使用mapStateToProps,或使用componentWillReceiveProps来触发状态更改。将所有内容放在redux存储和状态中,这是首选的长期选项,更易于维护和单元测试。

答案 1 :(得分:1)

我将所有状态放在redux存储上,不再使用本地状态,使用mapStateToProps使状态为道具,然后从中获取最新值。这是我认为的最佳做法:

  handleChange(event) {
    event.preventDefault();
    this.props.selectLayoutAction(event.target.value);
    this.props.resetStyles();
  }

  handleThemeChange(event) {
    event.preventDefault();
    this.props.setLayoutThemeAction({
      name: this.props.selectLayout,
      currentTheme: event.target.value
    });
  }

  render() {
      const { layouts, selectLayout } = this.props;
      let layoutsList = List(layouts);
      let currentTheme = '';

      if (layouts && layouts.get) {
        let targetLayout = layouts.find((layout) => layout.get('name') === selectLayout);
        currentTheme = targetLayout.get('currentTheme');
      }

      return (
        <div>
          <select onChange={this.handleChange.bind(this)} value={selectLayout}>
            {this.renderOptions(layoutsList)}
          </select>

          <select onChange={this.handleThemeChange.bind(this)} value={currentTheme}>
            {this.renderThemeOptions(selectLayout, layouts)}
          </select>
        </div>
      );
    }



function mapStateToProps(state) {
  console.log('Update selectLayout!!! ', state.selectLayout);
  syncSelectLayout = state.selectLayout;
  return {
    layouts: state.layouts,
    selectLayout: state.selectLayout
  };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({ selectLayoutAction, setLayoutThemeAction, resetStyles }, dispatch);
}