ReactJs - Redux 状态未在子组件的下拉列表中更新
ReactJs - Redux State is not updating in a dropdown in the child component
我正在尝试更新我的下拉列表中的项目,因为我的状态与玩家一起更新,但我失败了。请帮忙。
在子组件中,天窗对话框中有下拉菜单。
我正在使用以下代码打印来自该州的玩家数组的下拉列表。状态从 json.php(远程服务器)更新。
<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>
我可以在 console.log 中清楚地看到状态已正确更新并打印了 11 个玩家名称。但是在子组件中它不会更新下拉列表。
令人惊讶的是,在子组件中 componentWillReceiveProps() 会打印新的玩家名称,但下拉列表仍未更新。
请指教
Console.log 页面加载时输出
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 几秒后输出,因为数据是从 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() []
名为 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;
名为 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.currState = this.props.propStore.getState();
在 BowlingAddBowler
的构造函数中,仅在实例化 class 时第一次运行。您也可以将它放在 BowlingAddBowler
的 componentWillReceiveProps
中,以便它在新数据来自服务器和父组件更新时运行 BowlingAddBowler
.
我正在尝试更新我的下拉列表中的项目,因为我的状态与玩家一起更新,但我失败了。请帮忙。
在子组件中,天窗对话框中有下拉菜单。 我正在使用以下代码打印来自该州的玩家数组的下拉列表。状态从 json.php(远程服务器)更新。
<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>
我可以在 console.log 中清楚地看到状态已正确更新并打印了 11 个玩家名称。但是在子组件中它不会更新下拉列表。
令人惊讶的是,在子组件中 componentWillReceiveProps() 会打印新的玩家名称,但下拉列表仍未更新。
请指教
Console.log 页面加载时输出
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 几秒后输出,因为数据是从 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() []
名为 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;
名为 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.currState = this.props.propStore.getState();
在 BowlingAddBowler
的构造函数中,仅在实例化 class 时第一次运行。您也可以将它放在 BowlingAddBowler
的 componentWillReceiveProps
中,以便它在新数据来自服务器和父组件更新时运行 BowlingAddBowler
.