Home > front end >  How to delete item to list in react?
How to delete item to list in react?

Time:11-21

Also added a delete button but its not working, it says "Cannot read properties of undefined (reading 'deleteItem')" What am I doing wrong here?

<script type="text/babel">
            "use strict";
            
            class App extends React.Component {
              constructor(props) {
                super(props);
                this.state = {
                  items: [],
                  currentItem: {
                    text: "",
                    key: ""
                  }
                };
                this.handleInput = this.handleInput.bind(this);
                this.addItem = this.addItem.bind(this);
                this.deleteItem = this.deleteItem.bind(this);
                this.setUpdate = this.setUpdate.bind(this);
              }
              handleInput(e) {
                this.setState({
                  currentItem: {
                    text: e.target.value,
                    key: Date.now()
                  }
                });
              }
              addItem(e) {
                e.preventDefault();
                const newItem = this.state.currentItem;
                console.log(newItem);
                if (newItem.text !== "") {
                  const newItems = [...this.state.items, newItem];
                  this.setState({
                    items: newItems, // <-- should be new items array built above
                    currentItem: {
                      text: "",
                      key: ""
                    }
                  });
                }
              }

              deleteItem(key){
                const filteredItems= this.state.items.filter(item =>
                item.key!==key);
                this.setState({
                items: filteredItems
                })
            }

            setUpdate(text, key) {
               const items = this.state.items;
               items.map(item => {
                   if(item.key===key) {
                       item.text=text;
                   }
               })
               this.setState({
                   items: items
               })
            }
            
              render() {
                return (
                  <div>
                    <form id="to-do-form" onSubmit={this.addItem}>
                      <input
                        type="text"
                        placeholder="Enter Text"
                        value={this.state.currentItem.text}
                        onChange={this.handleInput}
                      />
                      <button type="submit">Add</button>
                    </form>
                    <ListItem items={this.state.items} 
                    deleteItem = {this.deleteItem}
                    setUpdate = {this.setUpdate}/>
                  </div>
                );
              }
            }
            
            class ListItem extends React.Component {
              render() {
                return (
                  <div>
                    {this.props.items.map((item) => {
                      return (
                        <div className="list" key={item.key}>
                          <p><input type="text" 
                            id={item.key} 
                            value={item.text} 
                            onChange ={
                                (e) => {
                                    this.props.setUpdate(e.target.value, item.key)
                                }
                            }
                            /><button onClick={() => this.prop.deleteItem(item.key)}>Ta bort</button></p>
                        </div>
                      );
                    })}
                  </div>
                );
              }
            }
            
            ReactDOM.render(<App />, document.getElementById('root'))
            </script>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

This is the first time I'm coding i react and I am trying to add a new list item to the list in but I get "TypeError: e.render is not a function" in the console... I want to have all my code in the HTML file like I have right now. Can you see what I am doing wrong here? This is my code so far:

<div id="root"></div>

<script type="text/babel">
"use strict";

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            items: [],
            currentItem: {
                text:'',
                key:''
            }
        }
        this.handleInput = this.handleInput.bind(this);
        this.addItem = this.addItem.bind(this);
    }
    handleInput(e) {
        this.setState({
            currentItem: {
                text: e.target.value,
                key: Date.now()
            }
        })
    }
    addItem(e) {
        e.preventDefault();
        const newItem = this.state.currentItem;
        console.log(newItem);
        if(newItem.text!=="") {
            const items=[...this.state.items, newItem];
            this.setState({
                items: newItems,
                currentItem: {
                    text:'',
                    key:''
                }
            })
        }
    }

   render() {
      return (
         <div>
            <form id="to-do-form" onSubmit={this.addItem}>
                <input type="text" placeholder="Enter Text"
                value={this.state.currentItem.text}
                onChange={this.handleInput}/>
                <button type="submit">Add</button>
            </form>
            <ListItem items = {this.state.items}></ListItem>
         </div>
      );
   }
}

class ListItem extends React.Component {
    constructor(props) {
        super(props);
        const items = props.items;
        const ListItems = items.map(items => {
            return <div className="list" key="item.key">
                    <p>{item.text}</p>
                </div>
        })
      return (
        <div>{ListItems}</div>
      )
    }
}
ReactDOM.render(<App />, document.getElementById('root'))
</script>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

You had a few misnamed variables. When adding items to this.state.items you were referencing an undeclared newItems variable when it should have been the items variable declared locally.

Additionally, the ListItem component was trying to save the passed props into a local class variable. Saving props locally is an anti-pattern in React, just render directly from the passed props values. ListItem also was not providing a render lifecycle method to return anything to render to the UI.

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="root"></div>

<script type="text/babel">
"use strict";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      items: [],
      currentItem: {
        text: "",
        key: ""
      }
    };
    this.handleInput = this.handleInput.bind(this);
    this.addItem = this.addItem.bind(this);
  }
  handleInput(e) {
    this.setState({
      currentItem: {
        text: e.target.value,
        key: Date.now()
      }
    });
  }
  addItem(e) {
    e.preventDefault();
    const newItem = this.state.currentItem;
    console.log(newItem);
    if (newItem.text !== "") {
      const newItems = [...this.state.items, newItem];
      this.setState({
        items: newItems, // <-- should be new items array built above
        currentItem: {
          text: "",
          key: ""
        }
      });
    }
  }

  render() {
    return (
      <div>
        <form id="to-do-form" onSubmit={this.addItem}>
          <input
            type="text"
            placeholder="Enter Text"
            value={this.state.currentItem.text}
            onChange={this.handleInput}
          />
          <button type="submit">Add</button>
        </form>
        <ListItem items={this.state.items} />
      </div>
    );
  }
}

class ListItem extends React.Component {
  render() {
    return (
      <div>
        {this.props.items.map((item) => {
          return (
            <div className="list" key={item.key}>
              <p>{item.text}</p>
            </div>
          );
        })}
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('root'))
</script>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related