【问题标题】:ReactJs - Redux State is not updating in a dropdown in the child componentReactJs - Redux 状态未在子组件的下拉列表中更新
【发布时间】:2017-07-08 16:57:54
【问题描述】:

我正在尝试更新下拉列表中的项目,因为我的状态与玩家一起更新,但我失败了。请帮忙。

在子组件中,我在 Skylight 对话框中有下拉菜单。 我正在使用以下代码从状态中打印玩家数组的下拉列表。状态从 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 对象 {id: 0, name: "", runs: 0, overs: 0, balls: 0…}

BowlingAddBowler 渲染() []

Console.log 从 php 获取数据几秒钟后输出

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

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

BowlingAddBowler 渲染() []

名为 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>
    )

    }
}

【问题讨论】:

    标签: reactjs react-redux react-jsx


    【解决方案1】:

    这段代码:

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

    BowlingAddBowler 的构造函数中,仅在类实例化时第一次运行。你也可以把它放在BowlingAddBowlercomponentWillReceiveProps 中,这样当新数据来自服务器和父组件更新BowlingAddBowler 时它就会运行。

    【讨论】:

    • 谢谢。修复。这么小的修复。来自 Angular,发现自己很难绑定所有内容。
    • 我建议你阅读教程和一些文档,你没有正确使用 React。上面的修复可以让你的代码正常工作,但是如果你的应用变大的话,你这样做的方式会给你带来麻烦。
    猜你喜欢
    • 2016-11-27
    • 1970-01-01
    • 2017-11-05
    • 1970-01-01
    • 1970-01-01
    • 2020-04-11
    • 1970-01-01
    • 1970-01-01
    • 2022-10-15
    相关资源
    最近更新 更多