Using setState to change multiple values within an array of objects -- ReactJS

react update state array of objects
react setstate array
react array of objects
react setstate nested array
react native array of objects
react native map array of objects
react array of inputs
usestate array of objects

I am new to React and wanted to write a fun project to get a hang of the language. I wanted to write a bubble blowing app, like so I wrote the following JSFiddle:

I am rendering an array of bubble objects stored in the following manner:

history =
 [ { //first element is empty placeholder
    diameter: 0,
    x: 0,
    y: 0
  }, 
  { 
    diameter: 40,
    x: 158,
    y: 122
  },
  { 
    diameter: 86,
    x: 274,
    y: 214
  },
  { 
    diameter: 26,
    x: 158,
    y: 244
  },
]

This exact array will produce the following result:

Now, after mocking this up, I got the crazy idea to add some gravity and bouncing. I wanted the bubbles to bounce like in this JSFiddle:

However, the only way I got the moving bubbles to work was by storing the information directly in state, as in the code below. (vy is the vertical speed of the ball.)

class Box extends React.Component {
constructor(props) {
    super(props);
    this.state = {
        diameter: 0,
        x: 0,
        y: 0,
        vy: 0,
        clicked: false,
    };
}

I use the following code to update the state of box in order to simulate the bouncing of the bubble:

fall(i){
    this.setState({
        y: this.state.y + i,
        vy: this.state.vy + .01,
    });
}

fallWrap(){
    this.fall(this.state.vy);
    this.u = setTimeout(this.fallWrap.bind(this), 1);



    if(this.state.y >= 400 - (this.state.diameter/2)){
        this.setState({
            y: 400 - (this.state.diameter/2),
            vy: -.9 * this.state.vy,
        }, function(){
            if(Math.abs(this.state.vy) < .2){
                clearTimeout(this.u);
            }
        });
    }

}

What I want to do is to store an array of multiple bubbles, like in the first JSfiddle, and have all the bubbles bounce around in the box like the second JS fiddle. This means updating value vy of multiple objects in the history array concurrently. I hope I have adequately described my needs. My central question is how can I use setstate to update a single value (vy) within each object stored within an array? For example, if I have

history =
 [ { 
    diameter: 0,
    x: 0,
    y: 0,
    vy: 0
  }, 
  { 
    diameter: 40,
    x: 158,
    y: 122,
    vy: .5 //update this
  },
  { 
    diameter: 86,
    x: 274,
    y: 214,
    vy: .4 //update this
  },
  { 
    diameter: 26,
    x: 158,
    y: 244
    vy: .23 //update this
  },
]

Then how I implement setState in a way that updates each vy? I know in React, state arrays should be immutable, so I am wondering if there is an established way to do this. The map function seems promising, but I don't know how to apply it here.

EDIT: Thanks everyone, I ended up solving my problem with Haken's solution. Here is a link to the JSFiddle

You can pass an updater function to setState. Here's an example of how this might work.

The object returned from the updater function will be merged into the previous state.

const updateBubble = ({y, vy, ...props}) => ({y: y + vy, vy: vy + 0.1, ...props})

this.setState(state => ({bubbles: state.bubbles.map(updateBubble)}))

Change the updateBubble function to add bouncing and so on.

Learn how to manipulate arrays in React state by using JavaScript array methods setState() method on a React component to update React's state. you can spread all key value pairs of the initial state object to the initial state of the component. That works with multiple properties in the state object too. When we declare a state variable with useState, it returns a pair — an array with two items. The first item is the current value, and the second is a function that lets us update it. Using [0] and [1] to access them is a bit confusing because they have a specific meaning. This is why we use array destructuring instead. Note

You can do this with map indeed. Here's how I would have done it.

One liner

this.setState({bubbles: this.state.bubbles.map(x => ({...x, vy: x.vy + 1})})

More explicit

this.state = {bubbles: history}

this.setState({ bubbles: this.state.bubbles.map(x => { 

    // Option 1 - more verbose
    let newBubble = x; // or even let newBubble = {...x}
    newBubble.vy = x.vy + 1;

    // Option 2 - directly update x
    x.vy = x.vy + 1

    // Then
    return x;
})})

I have a react app with two child components, one that has a single static input field individual dynamic input field to a corresponding element on an array. you want two inputs to modify a single array at two different indexes? setState({ inputs: updatedArray, }); } onChange(index, e.target.value)}/>)}. React/ReactJS: Update An Array State As in any web application, a React application too can have multiple checkboxes and/or selects . And the need to store such related input/option values as a homogenous collection necessitates the use of array states.

I would sugest you should change your approach. You should only manage the state as the first you showed, and then, in another component, manage multiple times the component you currently have.

You could use something like this:

import React from 'react'
import Box from './box'

export default class Boxes extends React.Component {
    constructor(props) {
        super(props);
        this.state = { 
            started:[false,false,false,false] /*these flags will be changed on your "onClick" event*/
        } 
    }
    render() {
        const {started} = this.state
        return(
            <div>
              {started[0] && <Box />}
              {started[1] && <Box />}
              {started[2] && <Box />}
              {started[3] && <Box />}
            </div>
        )
    }
}

Only the last object in the options object gets it's state changed. What is the best way to update multiple immutable values at once, and then pass  setState is the API method provided with the library so that the user is able to define and manipulate state over time. Three Rules of Thumb When Using setState( ) Do Not Modify State Directly wrong and right ways of setting state State Updates May Be Asynchronous. React may batch multiple setState() calls into a single update for performance.

Or an array of blog posts. The object contains the part of the state we want to update which, in this case, is the the change in value; React instructs the search component to update the value and the To demonstrate this idea further​, let's create a simple counter that increments and decrements on click. [React] Updating Nested Arrays with setState() I am trying to update state using React's setState(), but my state has nested arrays of objects. I tried mapping these but it doesn't seem to update and I can't find a way to log out the response from the method to see what's happening.

I knew that changing an input field created an event object and that line 2 was… the object's key in array brackets [key] you can dynamically set that key. setState({ [name]: value}) useful in React? For example --> <input In this way, no matter how complicated the object is, you can easily set a value to a property, even it’s nested in objects or arrays. (Using lensPath here so that you can set something like todoList.someObject.someNestedField .

There are a bunch of React hooks, but useState is the workhorse of the bunch. In this We'll also see a couple ways of storing multiple values. In classes, the state was always an object, and you could store useState returns an array with 2 elements, and we're using ES6 setState worked in classes! Whereas the array concat is used to add an item to an array, the array map method is useful to update item(s) in an array. It returns a new array too and thus doesn't mutate the previous array. Let's see how we can update an entire array by using the array map method.

Comments
  • You don't; you get the current state, you modify it, you set it back to the state. You could update any particular bubble and slice everything back together as you go, but I wouldn't bother.
  • I don't mind updating them all at the same time. For instance making a copy and modifying all the vy values and then setting it as the state. Hmm maybe that would work.
  • You don't need to make an explicit copy, e.g., see Håken's answer.
  • Thank you Dave!
  • This may be just what I'm looking for. I will try it out!
  • Thanks Haken! The balls bounce ad infinitum right now but I think I can fix that. here is the final.
  • Thanks Asten, Upvoted for expanding on Haken's answer and explaining the updater function more thoroughly.
  • Do you think you can elaborate on this some? By the way, I am looking for multiple bubbles, not boxes.