Si8
Si8

Reputation: 9225

What is the best way to update object array value in React

My React state:

//...
this.state = {
    mylist: [
        {
            "id": 0,
            "trueorfalse": false
        },
        {
            "id": 1,
            "trueorfalse": false
        }
    ]
}
//...

I am trying to update the trueorfalse value based on the id

Here is what I did so far but didn't work:

var idnum = e.target.id.toString().split("_")[1] //getting the id via an element id (0 or 1 in this case)
var TorF = true
if (type === 1) {
    this.setState({
        mylist: this.state.mylist.map(el => (el.id === idnum ? Object.assign({}, el, { TorF }) : el))
    })
}

I really want to make it dynamic so the trueorfase will be opposite of what it is now:

var idnum = e.target.id.toString().split("_")[1] //getting the id via an element id (0 or 1 in this case)
if (type === 1) {
    this.setState({
        mylist: this.state.mylist.map(el => (el.id === idnum ? Object.assign({}, el, { /* if already true set to false or vice versa */ }) : el))
    })
}

How can I update my code to have the dynamicity shown in the second example (if possible), otherwise the first example would do just fine

Upvotes: 0

Views: 166

Answers (2)

Joss Classey
Joss Classey

Reputation: 1062

Another solution using map:

Edit withered-field-889f8

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      mylist: [
        {
          id: 0,
          trueorfalse: false
        },
        {
          id: 1,
          trueorfalse: true
        }
      ]
    };
  }
  toggleBoolean = () => {
    const ID = Number(this.state.selectedID);
    this.setState(prevState => ({
      mylist: prevState.mylist.map(item => {
        if (item.id === ID) {
          return { ...item, trueorfalse: !item.trueorfalse };
        } else {
          return item;
        }
      })
    }));
  };
  render() {
    return (
      <div className="App">
        <p>{`State values: ${JSON.stringify(this.state.mylist)}`}</p>
        <button onClick={this.toggleBoolean}>Change true/false values</button>
        <label>Insert ID:</label>
        <input
          type="number"
          onChange={event => this.setState({ selectedID: event.target.value })}
        />
      </div>
    );
  }
}

Upvotes: 1

Michael
Michael

Reputation: 2773

I think the following code would accomplish your second question.

var idnum = e.target.id.toString().split("_")[1]
let newList = Array.from(this.state.mylist) //create new array so we don't modify state directly
if (type === 1) {
    let objToUpdate = newList.find((el) =>  el.id === idnum) // grab first element with matching id
    objToUpdate.trueorfalse = !objToUpdate.trueorfalse
    this.setState( { mylist: newList } )
}

Upvotes: 0

Related Questions