Redux:在子操作之后更新父组件数据

时间:2017-12-26 12:23:40

标签: reactjs redux reselect

我在初次store电话后Axios加载了一些数据。

然后我渲染两个组件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);
&#13;
&#13;
&#13;

player.js

&#13;
&#13;
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);
&#13;
&#13;
&#13;

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

我读过这篇文章:

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

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

我考虑像componentWillMountcomponentWillUpdate中的操作一样将数据发送到商店,但我不知道它是否正确。

2 个答案:

答案 0 :(得分:2)

在生命周期内调用一个动作没有任何问题,不建议在render方法中执行它,因为它触发了无限的动作,但在你的情况下如果你确实需要在子组件中进行这个计算我相信您应该在store.matchs.colorcomponentWillReceiveProps内发送此操作,在某些情况下,您实际上必须在两个地方都执行此操作。

去吧!

答案 1 :(得分:1)

docs非常明确:

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

如果您需要让子组件更新商店的方式,那么您需要执行dispatch一项操作,并将其放入ComponentWillMountComponentWillReceiveProps根据需要,有时你需要把它放在两者中。

但是,在旁注上,就像布鲁诺布拉加所说的那样,将逻辑放入其中似乎是错误的地方。 我建议将此逻辑放在reducer中,因为Component实际上不应该处理存储逻辑,只是通知(dispatch)状态更改。

另外,我认为你不需要将Player组件连接到redux商店,因为看起来每个玩家都拥有它自己的独立实例。

我建议将Player组件从Match组件传递给函数,例如

<Player ... onGoalScored={()=> this.handleGoalScored()} />

并在Match组件上执行:

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

并且在reducer中有逻辑,我们会说明Match的颜色应该是什么,以及在Match的下一次状态更新时,因为绑定到{{ 1}}将呈现为红色