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.