React state binding from child to parent

I am new to reactjs

I have a JSON array that consists of a task. I passed the array to a 2 ul list. One completed tasks and the other completed unfinished tasks. If I click on a task, the status changes but not updated in the other item. However, if I enter any text in the input state, then other items are set. Why isn't the state immediately set when I click on a 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

0


source to share


1 answer


This is because the parent TodoApp component that displays two lists does not know that something has changed in one of them. To do this, the child component must notify the parent component about it.

Add onStatusUpdate attribute for TodoList like this

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

      

This is how the update method can be determined



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

      

In the click handler of the 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/ `

+1


source







All Articles