简体   繁体   中英

ReactJs - Redux State is not updating in a dropdown in the child component

I am trying to update the items in my dropdown as my state updates with players BUT I am failing. Please help.

In the child component I have dropdown in the Skylight dialog box. I am using following code which prints the dropdown of the array of players from the state. State is updated from the json.php (remote server).

<select name="bowlerId"  value={this.state.bowlerId} onChange={this.handleInputChange} className="form-control">
            <option value="">Select an existing bowler</option>
            {
                this.currState.teamBowling.players.map(function (player, index) {
                return <option value="{player}" key={index}>{player}</option>
                })
            }
    </select>

I can clearly see in the console.log that the state is correctly updated and it prints 11 player names. But in the child component it does not update the dropdown.

Surprising enough, in the child component componentWillReceiveProps() does print new player names as they become availble but the dropdown is not updated still.

Please advise.

Console.log output as page loads

BowlingSummary render() Object {id: 0, name: "", runs: 0, overs: 0, balls: 0…}

PropStore Object {id: 0, name: "", runs: 0, overs: 0, balls: 0…}

BowlingAddBowler render() []

Console.log output after few seconds as data is fetched from php

BowlingSummary render() Object {id: 20, name: "Team Bowling", runs: 0, overs: 0, balls: 0…}

componentWillReceiveProps Object {id: 20, name: "Team Bowling", runs: 0, overs: 0, balls: 0…}

BowlingAddBowler render() []

Parent component named BowlingSummary

class BowlingSummary extends Component {

    render() {
    const { store }             = this.context;
    const currState             = store.getState();
    this.isBowlerBowling        = false;

    console.log('BowlingSummary render()', currState.teamBowling);

    return (
        <div>
        <div className="score-summary-bar">
            <div className="row">
            <div className="col-xs-4">Bowling</div>
            <div className="col-xs-1"></div>
            <div className="col-xs-1">Ovr</div>
            <div className="col-xs-1">Mdn</div>
            <div className="col-xs-1">Run</div>
            <div className="col-xs-1">Wkt</div>
            <div className="col-xs-1">Econ</div>
            <div className="col-xs-1">W</div>
            <div className="col-xs-1">N</div>
            </div>
        </div>

        <div className="score-summary-bowling">
            <div className="">
            {
            currState.teamBowling.players.map(function (player, index) {
                if ( player.isBowling === true ) {
                this.isBowlerBowling = true;
                return <BowlingBowler player={player} key={index}/>
                }
            })
            }
            </div>
            <div className="">
            {
                this.isBowlerBowling != true &&
                <BowlingAddBowler propStore={store} />

            }
            </div>
        </div>
        <div className="score-summary-bowling">
            <ScoreThisOver />
        </div>
        </div>
    );
    }
}

BowlingSummary.contextTypes = {
    store: PropTypes.object
}


export default BowlingSummary;

Child component named BowlingAddBowler

class BowlingAddBowler extends Component {

    constructor(props, context) {
    super(props, context);

    // Setup current state
    this.currState      = this.props.propStore.getState();
    console.log('PropStore', this.currState.teamBowling);

    // This component state
    this.state      = {
        bowlerId:               0,
        bowlerName:             '',
        markPrevOverFinished:   false
    };

    // Setup variables
    this.players    = this.props.players;

    // Bind this (so that we write short code in the onChange like onChange=this.func)
    this.handleInputChange = this.handleInputChange.bind(this);
    }

    componentWillReceiveProps(nextProps, nextState){
    //this.props.something // old value
    //nextProps.something // new value
    console.log('componentWillReceiveProps', nextProps.propStore.getState().teamBowling);
    }


    render() {
    //console.log('BowlingBowler render()', this.props);
    var responsiveWidth = {
        width:      '90vw',
        transform:  'translate(-23%, 0%)'
    };
    console.log('BowlingAddBowler render()', this.currState.teamBowling.players);

    return (
        <div className="row">
        <div className="col-xs-12">
            <button className="btn" onClick={() => this.refs.dialogAddBowler.show()}>No Bowler Selected. Click To Select</button>
        </div>
        <SkyLight dialogStyles={responsiveWidth} hideOnOverlayClicked ref="dialogAddBowler" title="Select a new bowler">
            <div>
            <form onSubmit={this.handleSubmit.bind(this)}>
                <label className="bg-yellow">
                Total <span className="text-red">0</span> for the loss of <span className="text-red">0</span> wickets in <span className="text-red">0</span> overs
                </label>
                <div className="spacer-horizontal"></div>

                <label>Who will bowl the next over ?</label>
                <select name="bowlerId"  value={this.state.bowlerId} onChange={this.handleInputChange} className="form-control">
                <option value="">Select an existing bowler</option>
                {
                    this.currState.teamBowling.players.map(function (player, index) {
                    return <option value="{player}" key={index}>{player}</option>
                    })
                }
                </select>
                <div className="spacer-horizontal"></div>

                <b>- OR -</b>
                <input type="text" name="bowlerName" value={this.state.bowlerName} onChange={this.handleInputChange} className="form-control" />
                <div className="spacer-horizontal"></div>

                <input type="checkbox" name="markPrevOverFinished" checked={this.state.markPrevOverFinished} onChange={this.handleInputChange}/>
                <label> Mark previous over finished</label>
                <div className="spacer-horizontal"></div>

                <div className="HorizLine"></div>
                <div className="text-right">
                <button type="submit" className="btn btn-primary"> Save </button>
                </div>
            </form>
            </div>
        </SkyLight>
        </div>
    )

    }
}

This code:

this.currState      = this.props.propStore.getState();

is in BowlingAddBowler 's constructor and only runs first time when the class is instantiated. You can put it in componentWillReceiveProps of BowlingAddBowler too so that it runs when new data comes from server and parent component updates BowlingAddBowler .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM