简体   繁体   中英

react state bind from child to parent element

I am new to reactJS

I have an JSON array which consists of task. I have rendered the the array to 2 ul list. One has completed tasks and the other has uncompleted tasks. If i click on the task the status is changing but it is not updated in other element. However if I enter some text in the input state is set to other elements. Why the state is not set immediately when I click on task?

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.3/JSXTransformer.js"></script>

<body>
<div id="todo">
</div>
<script type="text/jsx">
    var TodoList = React.createClass({
        clickHandle: function(index) {
            this.props.items[index].completed=!this.props.items[index].completed;
            console.log(this.props);
            this.setState({items: this.props.items});
        },
        render: function() {
          var createItem = function(itemText, index) {
            if(itemText.completed===this.props.completed)
                return <li key={index} onClick={this.clickHandle.bind(this,index)}>{itemText.text}</li>;
          };
          return <ul>{this.props.items.map(createItem, this)}</ul>;
        }
      });
      var TodoApp = React.createClass({
        getInitialState: function() {
          return {items: [{"text":"1true","completed":true},{"text":"2true","completed":true},{"text":"1false","completed":false}], text: ''};
        },
        onChange: function(e) {
          this.setState({text: e.target.value});
        },
        handleSubmit: function(e) {
          e.preventDefault();
          if(this.state.text!=''){
              this.state.items.push({"text":this.state.text,"completed":false});
              var nextText = '';
              this.setState({items:this.state.items,text: nextText});
          }
          else{
            alert("Enter some text!");
          }
        },
        render: function() {
          return (
            <div>
              <h3>TODO</h3>
              <TodoList items={this.state.items} completed={false}/>
              <TodoList items={this.state.items} completed={true}/>
              <form onSubmit={this.handleSubmit}>
                <input onChange={this.onChange} value={this.state.text} />
                <button>{'Add #' + (this.state.items.length + 1)}</button>
              </form>
            </div>
          );
        }
      });

      React.render(<TodoApp />, document.getElementById('todo'));

</script>

JSFiddle

This is happening because the parent component, TodoApp which renders the two lists does not know that something has changed in one of the them. For this the child component should notify the parent component about it.

Add a onStatusUpdate attribute to TodoList like this

<TodoList items={this.state.items} completed={false} onStatusUpdate={this.update}/>

This is how the update method can be defined

update: function(items){
  this.setState({items: items});
}

In the click handler of child component do something like this

clickHandle: function(index {
  this.props.items[index].completed=!this.props.items[index].completed;
  this.props.onStatusUpdate(this.props.items); // <-- this triggers the onStatusUpdate attribute defined in TodoList component
},

Here is an updated demo https://jsfiddle.net/dhirajbodicherla/aqqcg1sa/2/ `

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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