arkoak
arkoak

Reputation: 2497

Modify state data for non-child react component

I have two , mostly independent react classes

var User = React.createClass({
    ....
    updateGameScore: function(){ this.game1.score = .... } 
    render: function(){ return ( <div>{this.state.totalScore}</div>);
});


var Game = React.createClass({
    ....
    updateUserScore:function(){ how to access/modify parent here??? },
    render: function(){ return ( <div>{this.state.score}</div>);
});

I need to be able to update the user totalScore when game score changes and vice versa based on some formula (irrelevant here). The components are such that game is nested in the user as a child component but cannot be vice versa. Change in user score can update game score by passing down the variable using this.state(..) , however when game score changes, what way can I use to update the correct parent User score (there can be more than one users at a time)

Upvotes: 0

Views: 111

Answers (3)

Anthony Cregan
Anthony Cregan

Reputation: 983

In a situation like yours where two components do not share a common parent that can sensibly be used to store the change in state then you should use a store. I was unfamiliar with the concept until recently but people who know much more than me about these things recommend using Reflux as it is a streamlined/simplified version of the Flux architecture. Its simply a place to store and manipulate data independent of any one component but accessible to those components as required.

EDIT: Both Flux and Reflux seem to have been superseded by the excellent Redux.

Upvotes: 1

arkoak
arkoak

Reputation: 2497

I did another hack while waiting for the answer which also works and interesting to share for those who want to be able to call all public functions at root level.

  1. Assuming you have Croot class

    var Croot = React.createClass({
        ...
        anyPublicFunction(val){
           ...
        }
    });
    
  2. assign the result of render to a variable.

    var rootComponent = React.render(
        <Croot >..users & games here ...</Croot>,
        document.getElementById('lobbyArea')
    );
    
  3. Use that variable in any child node to call any public function of Croot

    rootComponent.anyPublicFunction(val);
    

Upvotes: 0

shtuper
shtuper

Reputation: 3916

You can pass a handler function from User to Game via props:

var User = React.createClass({
    ...
    handleScoreChange: function(newScore) {
        this.setState({totalScore: newScore});
    }

    render: function () {
        return (
            <Game handleScoreChange={this.handleScoreChange.bind(this)} />
        )
    }
});

var Game = React.createClass({
    ...
    updateUserScore: function() {
        this.props.handleScoreChange(this.state.score); 
    }
}

Upvotes: 2

Related Questions