1

So I am sort of new to React, I know the basics and tried to create a todo app but I can't figure out how to remove an item also is there any way I could improve this code? Obviously this does not have a remove button yet, I tried to add one. I couldn't figure out how to update state to remove a todo item as the todo items were being stored in state. Also this is in codepen that is why the react is in one file. Thanks!

html: <div id="html"></div>

css:

body {
  margin: 0;
}
* {
  box-sizing: border-box;
  font-family: sans-serif;
}
#html {
  background-color: lightblue;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}
h1 {
  text-align: center;
  font-size: 30px;
}
.add-element {
  display: flex;
  justify-content: center;
}
li {
  list-style: none;
  padding: 10px;
  background-color: rgba(182, 66, 245, 0.3);
  font-size: 20px;
  margin: 10px;
  max-width: 300px;
  word-wrap: break-word;
  border-radius: 7px;
  display: flex;
  justify-content: space-between;
}
li span {
  max-width: 250px;
}
ul {
  margin: 0;
  padding: 0;
}
input {
  border: none;
  border-top-left-radius: 10px;
  border-bottom-left-radius: 10px;
  padding: 10px 5px;
}
.add-btn {
  border: none;
  border-top-right-radius: 10px;
  border-bottom-right-radius: 10px;
}
input:focus,
.add-btn:focus,
.remove:focus {
  outline: none;
  border: 1px solid black;
}

Javascript/React:

const App = () => {
  return (
    <div>
      <h1>Simple React List App</h1>
      <List />
    </div>
  );
};
class List extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.handleClick = this.handleClick.bind(this);
    this.sendStateToParent = this.sendStateToParent.bind(this);
    this.state = { items: [], input: "" };
  }
  sendStateToParent() {
    console.log(this.state.items);
  }
  handleClick() {
    if (this.state.input === "") {
      alert("Add Something!");
    } else {
      console.log(this.state.input);
      this.setState(
        { items: [...this.state.items, this.state.input] },
        this.sendStateToParent
      );
      this.setState({ input: "" });
    }
    e.preventDefault();
  }
  handleChange(e) {
    this.setState({ input: e.target.value });
  }

  render() {
    return (
      <div>
        <div className="add-element">
          <input onChange={this.handleChange} value={this.state.input} />
          <button onClick={this.handleClick} class="add-btn">
            Add
          </button>
        </div>
        <ul>
          {this.state.items.map((item, i) => (
            <li key={i}>
              <span>{item}</span>    
            </li>
          ))}
        </ul>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("html"));

garrettsm
  • 21
  • 5
  • 1
    You can use [filter](https://stackoverflow.com/a/21688894/2873538) to remove an item from the list. – Ajeet Shah May 23 '21 at 16:53
  • Perhaps study https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_todo_list_beginning "DELETE" examples specifically jump to https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_interactivity_events_state#the_deletetask_callback_prop – Mark Schultheiss May 23 '21 at 16:55

2 Answers2

0

You need to use the filter higher order array function - MDN Reference. The code in in the handleDelete function.

  handleDelete(index) {
      const newTodos = this.state.items.filter((item, itemIndex) => {
        return itemIndex !== index
      })
     
    this.setState({items: newTodos})
  }

Solution

violet
  • 61
  • 4
  • Thank you, why does it have it set up with `{() => this.handleDelete(i)}` why can't it just be `{this.handleDelete}` like my others? – garrettsm May 23 '21 at 18:47
  • we need to pass the index of the item to the handleDelete function. handleDelete has one parameter, ´index´ – violet May 23 '21 at 18:54
0

You can use filter to create a new array which excludes the item being removed:

removeItem(item){
    this.setState({
        items: [...this.state.items.filter( itm => itm !== item)] 
    });
}
2human
  • 1