user6571878
user6571878

Reputation:

Why map function in ES6 is not refreshed?

I want to create a ToDo list, It store tasks in allTasks state and works when I push manually some data but doesn't show me in map function when I add an item with input.

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            inputValue: '',
            allTasks: []
        }

    this.addToList = this.addToList.bind(this);
    }

    addToList() {
        this.state.allTasks.push(this.state.inputValue);
    }

    render() {
        return (
          <div>
              <h1>کار های خود را مدیریت کنید !</h1>
              <input type="text" placeholder="کار خود را بنویسید ..." onChange={ event => this.setState({ inputValue: event.target.value }) } />
              <button onClick={ this.addToList }>ثبت کردن</button>
              <hr />
              <ul>
              {
                  this.state.allTasks.map(task => {
                      return <li>{ task }</li>;
                  })
              }
              </ul>
          </div>
        );
    }
}

Upvotes: 2

Views: 73

Answers (2)

Prakash Sharma
Prakash Sharma

Reputation: 16472

You are mutating the original state. Dont mutate the state, and use setState to rerender the ui.

addToList() {
   let k = [...this.state.allTasks];
   k.push(this.state.inputValue);
   this.setState({allTasks: k})
}

or
addToList() {
   this.setState({allTasks: [...this.state.allTasks, this.state.inputValue]})
}

Directly changing the state does not rerender the ui. You should avoid mutating state directly. Also using setState to update the state will rerender the ui.

let k = [...this.state.allTasks]; creates a new array, and then we push a value to k. So in this case we are not mutating the state directly. Instead we are changing a newly created array. After that we are using setState to set the state which will update the ui.

Upvotes: 6

Yash Thakur
Yash Thakur

Reputation: 1201

Here goes your answer:

class App extends Component {
   constructor(props) {
       super(props);
       this.state = {
          inputValue: '',
          allTasks: []
       };

       this.addToList = this.addToList.bind(this);
   }

   addToList(e) {
      if( e && e.preventDefault ) e.preventDefault();
      this.setState({
         allTasks: [...this.state.allTasks, this.state.inputValue]
      });
   }

   render() {
       return (
         <div>
             <h1>کار های خود را مدیریت کنید !</h1>
             <input type="text" placeholder="کار خود را بنویسید ..." value={this.state.inputValue} onChange={ event => this.setState({ inputValue: event.target.value }) } />
             <button onClick={ e => this.addToList(e) }>ثبت کردن</button>
             <hr />
             <ul>
                {
                   this.state.allTasks.map(task => {
                     return <li>{ task }</li>;
                   })
                }
             </ul>
         </div>
       );
   } 
}

Here this.setState updates the state and [...allTasks, this.state.inputValue] appends the inputValue to the array of allTasks. The changing in state makes the component rerender it and hence the updated value will be visible in your list.

Upvotes: -1

Related Questions