简体   繁体   English

在React中更新父道具

[英]Update parent props in React

Guys I have a modal in which I send array via props and set his state to be equal to this array.Then I'm adding element and its state is updating but its not updating the props...Can someone tell me what should I do in order to update his props ?? 伙计们,我有一个模态,我通过道具发送数组并将他的状态设置为等于这个数组。然后我添加了元素并且它的状态正在更新,但是它没有更新道具...做以更新他的道具?

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>
        );
    }
});

In my opinion, you shouldn't store items variable in Modal component state. 我认为,您不应该在Modal组件状态下存储items变量。

Store it only in props, and add onAddElement callback, which will be provided from parent component, like this: 仅将其存储在props中,并添加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.
  }
}

Next, in you parent component, you should define handleAddElement function and pass it to Modal component: 接下来,在父组件中,应定义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>
    );
  };
});

Hope, it helps! 希望能帮助到你!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM