0

I have a basic 'wrapper' component which contains child 'item' components

class Wrapper extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            items: []
       };
    }
    render() {
        return (
            <div>Items count- {this.state.items.length}
                    {this.state.items.map(function (item, i) {
                        <Item itemId={item.itemId} />
                    })}
            </div>
        );
    }
}




class Item extends React.Component {
    constructor(props) { super(props); }
    render() {
        return (
            <div class="item">{this.props.itemId}</div>
        );
    }
}

Do I call setState({ "items":[{ "itemId": 22 }] }); to update items in UI?

Want to add/remove 'item' and get UI updated accordingly.

2
  • You need to concatenate the old array with the new item using setState Commented Jan 2, 2019 at 17:14
  • Actually, I'm so geeking on React.JS but your question is not obvious, please leave some description, What actually you want to do? Commented Jan 2, 2019 at 17:15

3 Answers 3

2

For updates, you want to do something like the following...

// Update item
this.setState({ "items":this.state.items.map(function(item) {
    if (item.itemId !== 22) return item;
    // update item here

    // remember to return item
    return item
  })
});

// Remove item
this.setState({ "items":this.state.items.filter(item => {
  return item.itemId !== 22
})
})

// Add item
this.setState({ "items": this.state.items.concat(newItem)
})

I suggest putting these into React class methods though.

import React from 'react';

class Wrapper extends React.Component {
  constructor(props) {
      super(props);
      this.state = {
          items: []
     };
     this.addItem = this.addItem.bind(this)
     this.removeItem = this.removeItem.bind(this)
     this.updateItem = this.updateItem.bind(this)
  }
  addItem (item) {
    this.setState({
      items: this.state.items.concat(item)
    })
  }
  updateItem(id, updatedItem) {
    this.setState({
      items: this.state.items.map(function (item) {
        if (item.itemId !== id) return item;
        return updatedItem;
      })
    })
  }
  removeItem(id) {
    this.setState({
      items: this.state.items.filter(function(item) {
        return item.itemId !== id
      })
    })
  }
  render() {
      return (
          <div>Items count- {this.state.items.length}
            {this.state.items.map(function (item, i) {
                <Item itemId={item.itemId} />
            })}
          </div>
      );
  }
}




class Item extends React.Component {
  constructor(props) { super(props); }
  render() {
      return (
          <div class="item">{this.props.itemId}</div>
      );
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

This is a valid solution.
1

State is not mutable, so the code you've shown there will replace items with an array with one object. If you'd like to add/remove from the array, you'll first need to copy the array somehow , and replace with the new one. You should use the function argument of setState for that. Ex:

this.setState(function (currentState) {
  return {items: currentState.concat({itemId: 22})}
});

3 Comments

Nice! Can you show another version not using the spread operator?
on just use this.setState({ items: this.state.items.concat({itemId: 22}) })
Updated to not use spread operator. You should use the function version of setState though, since your next state is dependent on the previous.
0

This is how you add and remove to and from the state items array:

class Wrapper extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      items: []
    };
  }
  addItems = (id) => {
  // copies all current items and adds a new one
  this.setState({items: [...this.state.items, {itemId: id}]
  })
  }
  removeItems = (id) => {
  const newItemList = this.state.items.filter((item) => item.itemId !== id)
  this.setState({items: newItemList
  })
  }
  render() {
    return (
    <div>
    <div>Items count - {this.state.items.length}
      
      <button onClick={() => this.addItems(this.state.items.length + 1)}>Add Item</button>
      
      
      </div>
      {
        this.state.items.map((item) => { 
        return (
          <Item key={item.itemId} itemId={item.itemId} removeItems={this.removeItems} />
        )
        })
      } 
      </div>
    );
  }
}

ReactDOM.render(<Wrapper />, document.getElementById('root'))


class Item extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return <div className="item">test{this.props.itemId} <button onClick={() => this.props.removeItems(this.props.itemId)}>Remove Item</button></div>;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root'></div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.