Optiq
Optiq

Reputation: 3182

React: Updating array inside State with spread operator returns 1,000X more results than needed

I'm trying to update an array inside of my component's state from within a .map() method being run inside the render() method. There are currently 9 objects within the array I'm mapping that I wish to extract a property from and add to the array inside the state. When console.log()ing the state to see why my page was freezing for so long I saw that it was iterating 1,000 copies of each entry.

Here's an example of one of the nine objects I'm iterating over

{
  "name": "Trap_808",
  "key" : "Q",
  "path": "https://firebasestorage.googleapis.com/v0/b/online-coding.appspot.com/o/drum%20samples%2Ftrap-808-08.wav?alt=media&token=c3c63635-45b0-4c99-82ff-e397f1153fa0"
}

Here's how I have my state defined inside the constructor.

this.state = { currentSound: '', triggerKeys: [] };

What I'm trying to do is add the key property from the object to the triggerKeys property as the objects are iterated over. This is how I'm rendering the nine objects with the .map() method.

<ul id="pad-shell">
  {
    DRUM_PATCH.map( sound =>{
      this.setState({ triggerKeys: [...this.state.triggerKeys, sound.key] });

      console.log(this.state);

      return <DrumButton
               name={sound.name}
               soundKey={sound.key}
               sourceLink={sound.path}
               trigger={this.updateSound}
             />
     });
   }
</ul>

I also tried updating the state like this

this.setState( prevState =>{ return { triggerKeys: [...prevState.triggerKeys, sound.key] } });

The above example is actually the one that returns 9,000 entries, the code above it returns 1,000 of the same entry. Aside from this everything else is working as expected so I don't think there's anything else going on elsewhere in my code. Can anyone spot what the problem is? If you need more code let me know.

Upvotes: 0

Views: 258

Answers (2)

Tyler Sebastian
Tyler Sebastian

Reputation: 9458

As others have said, you should not use this.setState inside of render - doing so will most likely cause an infinite update loop.

You haven't provided enough code context to give you a definitive answer but

if DRUM_PATCH comes from props

class Component extends React.Component {
  constructor (props) {
    super(props)

    this.state = { triggerKeys: props.drumPatch.map(s => s.key) }
  }


  render() {
    ...
  }
}

if DRUM_PATCH is just a constant

this.state = { triggerKeys: props.drumPatch.map(s => s.key) }

becomes

this.state = { triggerKeys: DRUM_PATCH.map(s => s.key) }

Upvotes: 1

Atul
Atul

Reputation: 430

hey i guesss you are doing it in render function , if yes then everytime it changes the state, it will rerender and change the state again , it will be an infinite loop.

this.setState({ triggerKeys: [...this.state.triggerKeys, sound.key] });

this is the culprit

Upvotes: 1

Related Questions