【问题标题】:Redux: Update parent component data after child operationsRedux:子操作后更新父组件数据
【发布时间】:2017-12-26 12:23:39
【问题描述】:

在初始Axios 调用后,我在store 中加载了一些数据。

然后我渲染两个组件match(父组件)和player(子组件)。

这是以相关方式显示两个组件的方式(这是我原始代码的简化示例,在此示例中我可以用另一种方式解决我的问题,但在我复杂的实际代码中,必须这样做首先是子组件中的操作):

match.js

class Match extends Component {

  constructor(props) {
    super(props);
  }
 
  render() {
    return (    
      Object.values(this.props.matchs).map(( match_id ) => {
        let match = this.props.matchs[match_id];
        return (
         <div key={match_id}>
          <p>{match.tournament}</p>          
          <p>{match.color}</p> {/* this color depends of children condition*/ }
          <div className="players">
              {match.array_players.map ( ( player_id ) => {
                let player = this.props.players[player_id];
                  return (
                    <Player key={odd_id} ownPlayer={player} />
                  )
                })
          </div>
         </div> 
       )
      });    
    )  
  }
  
}

const mapStateToProps = state => {  
    return {
      matchs: state.matchs.matchs,
      players: state.players.players      
    };
  }
  
  const mapDispatchToProps = dispatch => {
    return {
      // actions
    };
  }
export default connect(mapStateToProps, mapDispatchToProps)(Matchs);

player.js

class Player extends Component {

  constructor(props) {
    super(props);
  } 

  render() {    
    
    return (

        <div>
          <p>{this.props.ownPlayer.name}</p>
          <p>{this.props.player_color}</p>
        </div>
    );
  }
}

const mapStateToProps = (state, ownProps) => {

  // I need to make some previous operations before render
  let player_color;
  if (ownProps.ownPlayer.name == "paul")
    player_color = 'yellow';
  else
    player_color = 'blue';
    
  // Then I Need to update parent component with children color condition
  // if (player_color == 'yellow')
  //  match_color = 'yellow'
  //    
  // Call some action here to update parent component???
  // things like these do not work: 
  // let id_p = ownProps.player.id_player;
  // state.players.players[id_p].color = 'blue'; This does not work


  return {    
    player_color
  };
};

const mapDispatchToProps = dispatch => {
  return {
    //
    }
  };
}

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

然后我需要在子组件中的某些条件之后更新父组件中的道具。

我读过这篇文章:

https://redux.js.org/docs/recipes/ComputingDerivedData.html

但是我不知道如何在渲染之前发送数据来存储和刷新父组件。

我想过像componentWillMountcomponentWillUpdate 中的操作一样调用以将数据发送到存储,但我不知道这是否正确。

【问题讨论】:

  • 如果你的子组件直接从它的父组件接收它的两个props(它们是它的变量),那么为什么你不能在父组件内部计算这个父组件的值呢?
  • 这是一个简单的例子,但在我的真实代码中,我需要在子项中进行一些复杂的计算,然后根据这些计算更新父组件的颜色(匹配)

标签: reactjs redux reselect


【解决方案1】:

在生命周期内调用动作没有错,不建议在 render 方法中执行,因为它会触发无限动作,但在您的情况下,如果您确实必须在子组件中进行此计算,我相信你应该在 componentWillReceivePropsComponentDidMount 内发送这个动作,在某些情况下你实际上必须在两个地方都这样做。

加油!

【讨论】:

    【解决方案2】:

    docs 很清楚:

    您可以在 constructor / ComponentWillMount / ComponentDidMount 中执行一次性操作,也可以在 ComponentWillReceiveProps 等循环生命周期方法中执行重复操作。

    如果您需要子组件更新商店的方法,那么您必须 dispatch 执行此操作,然后根据需要将其放入 ComponentWillMountComponentWillReceiveProps,有时你需要把它放在两者中。


    但是,顺便说一句,就像 Bruno Braga 所说的那样,它似乎确实是放置逻辑的错误位置。 我建议将此逻辑放在减速器中,因为组件确实不应该处理存储逻辑,只需通知 (dispatch) 状态更改。

    另外,我认为您不需要将 Player 组件连接到 redux 存储,因为似乎每个玩家都有自己的独立实例。

    我的建议是将Player 组件传递给Match 组件的函数,类似于

    &lt;Player ... onGoalScored={()=&gt; this.handleGoalScored()} /&gt;

    Match 组件上做:

    handleGoalScore() { this.props.dispatch(updateGoalsAction()) }

    并且在reducer中有逻辑,假设将找出Match的颜色应该是什么,并且在下一次状态更新到Match时,由于绑定到store.matchs.color将被渲染红色

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      • 2019-08-18
      • 2018-11-18
      • 2019-02-17
      • 2018-04-08
      • 2017-04-16
      相关资源
      最近更新 更多