KingdomConfusion
KingdomConfusion

Reputation: 11

How to add to a nested array in React?

I am building a Slack clone prototype. When I try to add a message to the array this.state.channels.message, it adds it instead as a new object in the array channels:

DESIRED OUTCOME

class App extends React.Component {
state = {
    channels : [
        { id: 1, name: 'react', messages: ['React message 1', '**DESIRED MESSAGE**']},
        { id: 2, name: 'react-router', messages: ['react-router message 1']},
    ],

CURRENT OUTCOME

class App extends React.Component {
state = {
    channels : [
        { id: 1, name: 'react', messages: ['React message 1']},
        { id: 2, name: 'react-router', messages: ['react-router message 1']},
        { id: 1, messages: '**DESIRED MESSAGE**'}
    ],

LOGIC TO UPDATE COMPONENT STATE

handleSentMessage = (value) => {
    const {selectedChannelId, selectedPersonId, channels} = this.state;

    if(this.state.selectedChannelId) {
      this.setState({
        ...this.state,
          channels: [
            ...this.state.channels,
            this.state.channels[selectedChannelId-1].messages.push(value)
          ]
        }
      );
    }

    if(this.state.selectedPersonId) {
      this.setState({
        ...this.state,
          people: [
            ...this.state.people,
            this.state.people[selectedPersonId-1].messages.push(value)
          ]
        }
      );
    }
}

Any help would be hugely appreciated! Github https://github.com/kingdomwilks/Slack2

Upvotes: 1

Views: 1028

Answers (1)

Dupocas
Dupocas

Reputation: 21297

You're spreading channels incorrectly, cause the second statement will not overwrite anything (it's an array not an object). Use map and only concat messages when the index of channel is equal to selectedChannelId - 1

this.setState(prevState =>({
    channels : prevState.channels.map((channel,i) =>{
        if(i === selectedChannelId -1) return {
            ...channel,
            messages: channel.messages.concat('foo') //Now you overwrite it
        }

        return channel
    })
}))

You could also directly use id to find the correct channel, this way you no longer need to selectedChannelId - 1, just selectedChannelId

Upvotes: 2

Related Questions