在React中更新父道具

时间:2016-08-05 12:43:06

标签: javascript reactjs

伙计我有一个模态,我通过道具发送数组并将其状态设置为等于此数组。然后我添加元素,其状态正在更新,但它没有更新道具......有人能告诉我我该怎么办才能更新他的道具?

var FormattedDate = ReactIntl.FormattedDate;
var DiaryTable = React.createClass({
    getInitialState: function() {
        return {
            items : this.props.item,
            globalChecked: false,
            startDate:new Date(),
            endDate:new Date(),
            hours:0
        };
    },
    handleChecked : function (i) {
        // console.log( this.state.items[i].selected);
        this.state.items[i].selected =  !this.state.items[i].selected;
        this.setState(this.state.items);
        // console.log( this.state.items[i].selected);
    },
    checkAll:function () {
        this.state.globalChecked = !this.state.globalChecked;
        var ifChecked = this.state.globalChecked;
        var newItems = this.state.items.map(function(element) {
            return { start: element.start,end:element.end,hours:element.hours,selected: ifChecked };
        });
        this.setState({items:newItems});
    },
    remove : function () {
        for(var i = 0;i<this.state.items.length;i++)
        {
            if(this.state.items[i].selected)
            {
               this.state.items.splice(i,1);
                i--;
            }
        }
        this.setState(this.state.items);
    },
    render: function(){
        var arrayItems =  this.state.items.map(function (item,i) {
            return (
                <tr key={i}>
                    <td><input type="checkbox"  checked={item.selected} onClick={this.handleChecked.bind(this,i)}/></td>
                    <td><FormattedDate value={item.start}/></td>
                    <td><FormattedDate value={item.end}/></td>
                    <td>{item.hours}</td>
                    <td>
                        <button className="editButton"></button>
                    </td>
                </tr>
            );
        }.bind(this));

        return (
                <table className="myTable">
                    <thead>
                    <tr>
                    <th><input type="checkbox" onClick={this.checkAll}/></th>
                    <th>Start Date:</th>
                    <th>End Date:</th>
                    <th id="hoursField">Hours:</th>
                    <th id="editField">Edit:</th>
                    </tr>
                    </thead>
                    <tbody>
                    {arrayItems}
                    </tbody>
                    <tfoot>
                    <tr>
                    <td colSpan="4">
                        <span className="addButtonDisplay"><Modal items={this.state.items}></Modal></span>
                        <button className="myButton" onClick={this.remove}>Remove period</button>
                        <button className="myButton">Set result from merge</button>
                    </td>
                        </tr>
                    </tfoot>
                </table>
        );
    }
 });

var Modal = React.createClass({
    getInitialState() {
        return {
            items:this.props.items,
            show: false,
            startDate:null,
            endDate:null
        };
    },
    handleChangeStartDate:function (date) {
        this.setState({
            startDate:date
        });
    },
    handleChangeEndDate:function (date) {
        this.setState({
            endDate:date
        });
    },
    showModal() {
        this.setState({show: true});
    },

    hideModal() {
        this.setState({show: false});
    },
    addElement:function () {
        var workHours = this.workHours.value;
        var objectToAdd = {start:this.state.startDate,end:this.state.endDate,hours:workHours};
        this.state.items.push(objectToAdd);
        this.setState({items:this.state.items});
        this.state.startDate = null;
        this.state.endDate = null;
        this.setState({show: false});
    },
    render : function(){
        var close = () => this.setState({ show: false});
        return (
            <ReactBootstrap.ButtonToolbar>
                <button className="myButton" onClick={() => this.setState({ show: true})}>Add period</button>
                <ReactBootstrap.Modal show={this.state.show} onHide={this.hideModal} dialogClassName="custom-modal">
                    <ReactBootstrap.Modal.Header closeButton>
                        <ReactBootstrap.Modal.Title id="contained-modal-title-lg">Modal heading</ReactBootstrap.Modal.Title>
                    </ReactBootstrap.Modal.Header>
                    <ReactBootstrap.Modal.Body>
                       <form name="myForm">
                                <div>
                                    <span id="example">Enter Start Date: </span>
                                    <DatePicker selected={this.state.startDate} onChange={this.handleChangeStartDate} className="datepickerStartAlignment"/>
                                </div>

                                <div>
                                    <span>Enter End Date: </span>
                                    <DatePicker selected={this.state.endDate} onChange={this.handleChangeEndDate} className="datepickerEndAlignment"/>
                                </div>
                                <div>
                                    <span>Enter Work Hours: </span>
                                    <input ref={(ref) => this.workHours = ref} onChange={this.state.handleChangeWorkHours} id="hoursInput" name="workHours" type="number" min="0" required/>
                                </div>
                        </form>

                    </ReactBootstrap.Modal.Body>
                    <ReactBootstrap.Modal.Footer>
                        <ReactBootstrap.Button bsStyle="primary" onClick={this.addElement}>Add</ReactBootstrap.Button>
                        <ReactBootstrap.Button bsStyle="primary" onClick={this.hideModal}>Close</ReactBootstrap.Button>
                    </ReactBootstrap.Modal.Footer>
                </ReactBootstrap.Modal>
           </ReactBootstrap.ButtonToolbar>
        );
    }
});

1 个答案:

答案 0 :(得分:1)

在我看来,您不应该将items变量存储在Modal组件状态中。

仅将其存储在道具中,并添加onAddElement回调,这将从父组件提供,如下所示:

// Modal.js
var Modal = React.createClass({
  getInitialState() {
    return {
      show: false,
      startDate:null,
      endDate:null
    };
  },

  // Other methods...

  addElement: function () {
    var workHours = this.workHours.value;
    var objectToAdd = {start:this.state.startDate,end:this.state.endDate,hours:workHours};

    // Instead of adding object to state, we are providing it to callback.
    this.props.onAddElement(objectToAdd);

    // Also, you shouldn't change existing state values, provide them to `setState` function instead.
    this.setState({
      show: false,
      startDate: null,
      endDate: null
    });
  },

  render: function() {
    // Your render code.
  }
}

接下来,在您的父组件中,您应该定义handleAddElement函数并将其传递给Modal组件:

// DiaryTable.js
var DiaryTable = React.createClass({
  // Defining `handleAddElement` function, which will be invoked
  // everytime you add new element
  handleAddElement: function(element) {
    this.setState({
      // `concat` method returns new array with appended element.
      items: this.state.items.concat(element)
    });
  }

  render: function() {
    // I removed other markup, to made explanation more clear.
    return (
      <Modal items={this.state.items} onAddElement={this.handleAddElement.bind(this)}></Modal>
    );
  };
});

希望,这有帮助!