【问题标题】:reactjs updating parent state from child in map functionreactjs在地图功能中从孩子更新父状态
【发布时间】:2015-06-23 20:27:19
【问题描述】:

我目前有两个组件LootBoxLootTableLootTableLootBox 的孩子。

var LootBox = React.createClass({
            loadLootFromServer: function() {
                $.ajax({
                  url: this.props.url,
                  dataType: 'json',
                  cache: false,
                  success: function(data) {
                    this.setState({data: data});
                  }.bind(this),
                  error: function(xhr, status, err) {
                    console.error(this.props.url, status, err.toString());
                  }.bind(this)
                });
            },
            loadItemsFromServer: function() {
                $.ajax({
                  url: this.props.itemData,
                  dataType: 'json',
                  cache: false,
                  success: function(bossData) {
                    this.setState({bossData: bossData, loading: {"done": true}});
                  }.bind(this),
                  error: function(xhr, status, err) {
                    console.error(this.props.itemData, status, err.toString());
                  }.bind(this)
                });
            },
            handleClick: function(e, slot, item_id, item_bonus) {
                e.preventDefault();
                this.state.data.head.id = item_id;
                this.state.data.head.bonus = item_bonus;
                this.setState({data: this.state.data});
            },
            getInitialState: function() {
                return {
                    data: {
                        main_hand: {},
                        off_hand: {},
                        head: {},
                        neck: {},
                        shoulders: {},
                        back: {},
                        chest: {},
                        wrist: {},
                        hands: {},
                        waist: {},
                        legs: {},
                        feet: {},
                        finger1: {},
                        finger2: {},
                        trinket1: {},
                        trinket2: {}
                    },
                    bossData: {
                        main_hand: [],
                        off_hand: [],
                        head: [],
                        neck: [],
                        shoulders: [],
                        back: [],
                        chest: [],
                        wrist: [],
                        hands: [],
                        waist: [],
                        legs: [],
                        feet: [],
                        fingers: [],
                        trinkets: [],

                    },
                    loading: {"done": false}
                };
            },
            componentDidMount: function() {
                this.loadLootFromServer();
                this.loadItemsFromServer();
            },
            render: function () {
                if(this.state.loading.done == false){
                    return (<div id="spin"></div>)
                }
                else {
                    return (
                        <LootTable data={this.state.data} bossData={this.state.bossData} handleClick={this.handleClick} />
                    )
                }
            } 
        });

        var LootTable = React.createClass({
            render: function () {
                return (
                    <div className="table-responsive">
                        <table className="table table-bordered table-hover">
                            <tr>
                                <th>Head <a href="#" data-toggle="collapse" data-target="#items_head"><span className="glyphicon glyphicon-th-list pull-right"></span></a></th>
                                <th>Neck <a href="#" data-toggle="collapse" data-target="#items_neck"><span className="glyphicon glyphicon-th-list pull-right"></span></a></th>
                            </tr>
                            <tr>
                                <td>
                                    <a href={"http://wowhead.com/item=".concat(this.props.data.head.id, "&bonus=", this.props.data.head.bonus)}>{this.props.data.head.id}</a>
                                    <div id="items_head" className="collapse"><h4>Select Replacement Item</h4>

                                        {this.props.bossData.head.map(function(item, i, this.props.handleClick){
                                        return (<div key={"item_"+item.id}>
                                            <a href="#" onClick={this.props.handleClick.bind(null, 'head', item.id, item.bonus)} rel={"item=".concat(item.id, "&bonus=", item.bonus)}>{item.name}</a>
                                        </div>);
                                    })}</div>
                                </td>
                                <td>
                                    <a href={"http://wowhead.com/item=".concat(this.props.data.neck.id, "&bonus=", this.props.data.neck.bonus)}>{this.props.data.neck.id}</a>
                                    <div id="items_neck" className="collapse"><h4>Select Replacement Item</h4>
                                        {this.props.bossData.neck.map(function(item){
                                        return (<div key={"item_"+item.id}>
                                            <a href="#" rel={"item=".concat(item.id, "&bonus=", item.bonus)}>{item.name}</a>
                                        </div>);
                                    })}</div>
                                </td>
                            </tr>
                            <tr>
                                <th>Shoulders <a href="#" data-toggle="collapse" data-target="#items_shoulders"><span className="glyphicon glyphicon-th-list pull-right"></span></a></th>
                                <th>Chest <a href="#" data-toggle="collapse" data-target="#items_chest"><span className="glyphicon glyphicon-th-list pull-right"></span></a></th>
                            </tr>
                            <tr>
                                <td>
                                    <a href={"http://wowhead.com/item=".concat(this.props.data.shoulders.id, "&bonus=", this.props.data.shoulders.bonus)}>{this.props.data.shoulders.id}</a>
                                    <div id="items_shoulders" className="collapse"><h4>Select Replacement Item</h4>
                                        {this.props.bossData.shoulders.map(function(item){
                                        return (<div key={"item_"+item.id}>
                                            <a href="#" rel={"item=".concat(item.id, "&bonus=", item.bonus)}>{item.name}</a>
                                        </div>);
                                    })}</div>
                                </td>
                                <td>
                                    <a href={"http://wowhead.com/item=".concat(this.props.data.chest.id, "&bonus=", this.props.data.chest.bonus)}>{this.props.data.chest.id}</a>
                                    <div id="items_chest" className="collapse"><h4>Select Replacement Item</h4>
                                        {this.props.bossData.chest.map(function(item){
                                        return (<div key={"item_"+item.id}>
                                            <a href="#" rel={"item=".concat(item.id, "&bonus=", item.bonus)}>{item.name}</a>
                                        </div>);
                                    })}</div>
                                </td>
                            </tr>
                            <tr>
                                <th>Waist <a href="#" data-toggle="collapse" data-target="#items_waist"><span className="glyphicon glyphicon-th-list pull-right"></span></a></th>
                                <th>Legs <a href="#" data-toggle="collapse" data-target="#items_legs"><span className="glyphicon glyphicon-th-list pull-right"></span></a></th>
                            </tr>
                            <tr>
                                <td>
                                    <a href={"http://wowhead.com/item=".concat(this.props.data.waist.id, "&bonus=", this.props.data.waist.bonus)}>{this.props.data.waist.id}</a>
                                    <div id="items_waist" className="collapse"><h4>Select Replacement Item</h4>
                                        {this.props.bossData.waist.map(function(item){
                                        return (<div key={"item_"+item.id}>
                                            <a href="#" rel={"item=".concat(item.id, "&bonus=", item.bonus)}>{item.name}</a>
                                        </div>);
                                    })}</div>
                                </td>
                                <td>
                                    <a href={"http://wowhead.com/item=".concat(this.props.data.legs.id, "&bonus=", this.props.data.legs.bonus)}>{this.props.data.legs.id}</a>
                                    <div id="items_legs" className="collapse"><h4>Select Replacement Item</h4>
                                        {this.props.bossData.legs.map(function(item){
                                        return (<div key={"item_"+item.id}>
                                            <a href="#" rel={"item=".concat(item.id, "&bonus=", item.bonus)}>{item.name}</a>
                                        </div>);
                                    })}</div>
                                </td>
                            </tr>
                            <tr>
                                <th>Feet <a href="#" data-toggle="collapse" data-target="#items_feet"><span className="glyphicon glyphicon-th-list pull-right"></span></a></th>
                                <th>Wrist <a href="#" data-toggle="collapse" data-target="#items_wrist"><span className="glyphicon glyphicon-th-list pull-right"></span></a></th>
                            </tr>
                            <tr>
                                <td>
                                    <a href={"http://wowhead.com/item=".concat(this.props.data.feet.id, "&bonus=", this.props.data.feet.bonus)}>{this.props.data.feet.id}</a>
                                    <div id="items_feet" className="collapse"><h4>Select Replacement Item</h4>
                                        {this.props.bossData.feet.map(function(item){
                                        return (<div key={"item_"+item.id}>
                                            <a href="#" rel={"item=".concat(item.id, "&bonus=", item.bonus)}>{item.name}</a>
                                        </div>);
                                    })}</div>
                                </td>
                                <td>
                                    <a href={"http://wowhead.com/item=".concat(this.props.data.wrist.id, "&bonus=", this.props.data.wrist.bonus)}>{this.props.data.wrist.id}</a>
                                    <div id="items_wrist" className="collapse"><h4>Select Replacement Item</h4>
                                        {this.props.bossData.wrist.map(function(item){
                                        return (<div key={"item_"+item.id}>
                                            <a href="#" rel={"item=".concat(item.id, "&bonus=", item.bonus)}>{item.name}</a>
                                        </div>);
                                    })}</div>
                                </td>
                            </tr>
                            <tr>
                                <th>Hands <a href="#" data-toggle="collapse" data-target="#items_hands"><span className="glyphicon glyphicon-th-list pull-right"></span></a></th>
                                <th>Back <a href="#" data-toggle="collapse" data-target="#items_back"><span className="glyphicon glyphicon-th-list pull-right"></span></a></th>
                            </tr>
                            <tr>
                                <td>
                                    <a href={"http://wowhead.com/item=".concat(this.props.data.hands.id, "&bonus=", this.props.data.hands.bonus)}>{this.props.data.hands.id}</a>
                                    <div id="items_hands" className="collapse"><h4>Select Replacement Item</h4>
                                        {this.props.bossData.hands.map(function(item){
                                        return (<div key={"item_"+item.id}>
                                            <a href="#" rel={"item=".concat(item.id, "&bonus=", item.bonus)}>{item.name}</a>
                                        </div>);
                                    })}</div>
                                </td>
                                <td>
                                    <a href={"http://wowhead.com/item=".concat(this.props.data.back.id, "&bonus=", this.props.data.back.bonus)}>{this.props.data.back.id}</a>
                                    <div id="items_back" className="collapse"><h4>Select Replacement Item</h4>
                                        {this.props.bossData.back.map(function(item){
                                        return (<div key={"item_"+item.id}>
                                            <a href="#" rel={"item=".concat(item.id, "&bonus=", item.bonus)}>{item.name}</a>
                                        </div>);
                                    })}</div>
                                </td>
                            </tr>
                            <tr>
                                <th>Finger 1 <a href="#" data-toggle="collapse" data-target="#items_finger1"><span className="glyphicon glyphicon-th-list pull-right"></span></a></th>
                                <th>Finger 2 <a href="#" data-toggle="collapse" data-target="#items_finger2"><span className="glyphicon glyphicon-th-list pull-right"></span></a></th>
                            </tr>
                            <tr>
                                <td>
                                    <a href={"http://wowhead.com/item=".concat(this.props.data.finger1.id, "&bonus=", this.props.data.finger1.bonus)}>{this.props.data.finger1.id}</a>
                                    <div id="items_finger1" className="collapse"><h4>Select Replacement Item</h4>
                                        {this.props.bossData.fingers.map(function(item){
                                        return (<div key={"item1_"+item.id}>
                                            <a href="#" rel={"item=".concat(item.id, "&bonus=", item.bonus)}>{item.name}</a>
                                        </div>);
                                    })}</div>
                                </td>
                                <td>
                                    <a href={"http://wowhead.com/item=".concat(this.props.data.finger2.id, "&bonus=", this.props.data.finger2.bonus)}>{this.props.data.finger2.id}</a>
                                    <div id="items_finger2" className="collapse"><h4>Select Replacement Item</h4>
                                        {this.props.bossData.fingers.map(function(item){
                                        return (<div key={"item2_"+item.id}>
                                            <a href="#" rel={"item=".concat(item.id, "&bonus=", item.bonus)}>{item.name}</a>
                                        </div>);
                                    })}</div>
                                </td>
                            </tr>
                            <tr>
                                <th>Trinket 1 <a href="#" data-toggle="collapse" data-target="#items_trinket1"><span className="glyphicon glyphicon-th-list pull-right"></span></a></th>
                                <th>Trinket 2 <a href="#" data-toggle="collapse" data-target="#items_trinket2"><span className="glyphicon glyphicon-th-list pull-right"></span></a></th>
                            </tr>
                            <tr>
                                <td>
                                    <a href={"http://wowhead.com/item=".concat(this.props.data.trinket1.id, "&bonus=", this.props.data.trinket1.bonus)}>{this.props.data.trinket1.id}</a>
                                    <div id="items_trinket1" className="collapse"><h4>Select Replacement Item</h4>
                                        {this.props.bossData.trinkets.map(function(item){
                                        return (<div key={"item1_"+item.id}>
                                            <a href="#" rel={"item=".concat(item.id, "&bonus=", item.bonus)}>{item.name}</a>
                                        </div>);
                                    })}</div>
                                </td>
                                <td>
                                    <a href={"http://wowhead.com/item=".concat(this.props.data.trinket2.id, "&bonus=", this.props.data.trinket2.bonus)}>{this.props.data.trinket2.id}</a>
                                    <div id="items_trinket2" className="collapse"><h4>Select Replacement Item</h4>
                                        {this.props.bossData.trinkets.map(function(item){
                                        return (<div key={"item2_"+item.id}>
                                            <a href="#" rel={"item=".concat(item.id, "&bonus=", item.bonus)}>{item.name}</a>
                                        </div>);
                                    })}</div>
                                </td>
                            </tr>
                            <tr>
                                <th>Main Hand <a href="#" data-toggle="collapse" data-target="#items_main_hand"><span className="glyphicon glyphicon-th-list pull-right"></span></a></th>
                                <th>Off Hand <a href="#" data-toggle="collapse" data-target="#items_off_hand"><span className="glyphicon glyphicon-th-list pull-right"></span></a></th>
                            </tr>
                            <tr>
                                <td>
                                    <a href={"http://wowhead.com/item=".concat(this.props.data.main_hand.id, "&bonus=", this.props.data.main_hand.bonus)}>{this.props.data.main_hand.id}</a>
                                    <div id="items_main_hand" className="collapse"><h4>Select Replacement Item</h4>
                                        {this.props.bossData.main_hand.map(function(item){
                                        return (<div key={"item_"+item.id}>
                                            <a href="#" rel={"item=".concat(item.id, "&bonus=", item.bonus)}>{item.name}</a>
                                        </div>);
                                    })}</div>
                                </td>
                                <td>
                                    <a href={"http://wowhead.com/item=".concat(this.props.data.off_hand.id, "&bonus=", this.props.data.off_hand.bonus)}>{this.props.data.off_hand.id}</a>
                                    <div id="items_off_hand" className="collapse"><h4>Select Replacement Item</h4>
                                        {this.props.bossData.off_hand.map(function(item){
                                        return (<div key={"item_"+item.id}>
                                            <a href="#" rel={"item=".concat(item.id, "&bonus=", item.bonus)}>{item.name}</a>
                                        </div>);
                                    })}</div>
                                </td>
                            </tr>
                        </table>
                    </div>
                )
            }
        });

        React.render(
            <LootBox url="/loot.json" itemData='/bosses.json' />,
            document.getElementById('content')
        );

基本上我在这里想要实现的是,当在LootTable 中单击链接时更改data 的状态。

每当用户点击{this.props.BossData.head.map(... 地图中的链接时,E.G。我需要它来更新this.state.data.head.idthis.state.data.head.bonus

我已经为此苦苦思索了好几个小时,并尝试了各种解决方案,但均无济于事。

如果我尝试绑定this.props.handleClick,它告诉我无法读取未定义的属性绑定。有人有什么想法吗?

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    映射函数内部的this 与映射函数外部的this 上下文不同。但是,您可以将您想要的 this-context 传递给map

    所以,试着让你的地图功能类似于

    this.props.bossData.head.map(function(item) {
      return <a onClick={this.props.handleClick.bind....} //You fill in the rest
    }, this);
    

    【讨论】:

    • 我很高兴你确认了这一点,我怀疑它不是同一个上下文,但我不知道如何改变这个问题。我现在就试试看。
    猜你喜欢
    • 2014-05-14
    • 1970-01-01
    • 1970-01-01
    • 2018-10-09
    • 2021-01-21
    • 1970-01-01
    • 2015-06-14
    • 1970-01-01
    • 2016-10-02
    相关资源
    最近更新 更多