Sumit Joshi
Sumit Joshi

Reputation: 89

Trying to make a to-do-list using react

After adding the item into the input, when clicking the button to add the items on the list, its only creating the li element and the user input is not there.

constructor() {
    super();

    this.state = {
      userInput: "",
      list: []
    };
  }

  changeUserInput = Input => {
    this.setState({ userInput: Input.target.value });
  };
  onButtonSubmit = Input => {
    let listArray = this.state.list;
    listArray.push(Input);
    this.setState({ list: listArray });
  };

  render() {
    return (
      <div className="App">
        <Input
          changeUserInput={this.changeUserInput}
          onButtonSubmit={this.onButtonSubmit}
        />
        <ul>
          {this.state.list.map((val, index) => (
            <li key={index}>{val}</li>
          ))}
        </ul>
      </div>
    );
  }

//Input.js

const Input = ({ changeUserInput, onButtonSubmit }) => {
  return (
    <div>
      <p className="f2">{"Make a shopping list by adding items"}</p>
      <div>
        <input
          className="w-70 ma2 pa2 br-pill"
          type="text"
          placeholder="enter items"
          onChange={changeUserInput}
        />
        <div>
          <button
            className="f6 grow br-pill ba bw1 ph3 pv2 mb2 dib black
    pointer"
            onClick={() => {
              onButtonSubmit();
            }}
          >
            Add Item
          </button>
        </div>
      </div>
    </div>
  );
};
  1. List item

    expected the output like .Item but the out put is only .

Upvotes: 4

Views: 99

Answers (4)

Arnaud Christ
Arnaud Christ

Reputation: 3551

In your onButtonSubmit function you are trying to add Input in the list but you should add this.state.userInput

onButtonSubmit = () => {
  this.setState({list: [...this.state.list, this.state.userInput]})
}

Edit: As mentioned in other answers, it's safer to use spread operator as it is not mutating the original array but creating a new one.

Upvotes: 1

ravibagul91
ravibagul91

Reputation: 20755

You are directly mutating the state, which you should never do.

As you already have input change handler, your submit function should be,

onButtonSubmit = () => {
  this.setState(prevState => ({
    ...prevState, 
    list:prevState.list.concat(this.state.userInput),
    userInput:''
  }
  ),()=>console.log(this.state))
}

Demo

Upvotes: 2

Icepickle
Icepickle

Reputation: 12796

You are not sending a parameter to your onButtonSubmit function, if you look at this:

<button 
  className= 'f6 grow br-pill ba bw1 ph3 pv2 mb2 dib blackpointer' 
  onClick ={() => {onButtonSubmit()}} >Add Item</button>

There is no argument supplied, however, you do expect one here:

onButtonSubmit = (Input) => {
  let listArray = this.state.list;
  listArray.push(Input);
  this.setState({list: listArray})
}

More interestingly, the change handler, you set the current user input value here:

changeUserInput = (Input) => {
  this.setState({userInput: Input.target.value});
} 

So your submission, should probably be more like

onButtonSubmit = () => {
  let listArray = [...this.state.list, this.state.userInput];
  this.setState({ list: listArray, userInput: undefined })
}

Where you would create a new array from the current list state, add the new userInput value and then update the state (and reset the current user input)

Upvotes: 1

mukesh210
mukesh210

Reputation: 2892

Always treat this.state as if it were immutable. Your should not modify array by appending values in it.

Try below approach:

const { list } = this.state;
const newList = [...list, Input]
this.setState({ list: newList })

Upvotes: 1

Related Questions