1

I'm new in React, and I would like to know If someone could help me with this. I have an application like slack, where I can add a new Team and add a channel. The problem is that is a complex DS and I have been trying to modify the state with new data passed through inputs, either in team and channel, but I have not had success

import React, { Component } from "react";
import { render } from "react-dom";
import "./style.css";

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      newTeamValue: "",
      teams: [
        {
          newChannel: "",
          name: "Team1",
          channels: [ 
            {
              name: "Channel1",
              index: 1
            },
            {
              name: "Channel2",
              index: 2
            }
          ]
        }
      ]
    };
    this.addTeam = this.addTeam.bind(this)

    this.addChannel = this.addChannel.bind(this)
  }

  addTeam(e) {
    e.preventDefault();
    this.setState(prevState => ({
      newTeam: "",
      teams: [
        ...prevState.teams,
        {
          name: this.state.newTeam,
          channels: []
        }
      ]
    }));
  }

  addChannel(e){
    e.preventDefault()
    this.setState(prevState => ({
      newChannel:"",
      teams: [
        ...prevState.teams,
        {
          channels: [...prevState, {
            name: this.state.teams.newChannel
          }]
        }
      ]
    }))
  }

  render() {
    return (
      <div>
        <ul>
          {this.state.teams.map(team => {
            return (
              <div>
                <li>{team.name}</li>
                <input onChange={e => this.setState({ newChannel: e.target.value })} value={this.state.newChannel} />
                <button onClick={this.addChannel}>Add New Channel</button>
                <ul>
                  {team.channels.map(channel => {
                    return (
                      <div>
                        <h2>{channel.name}</h2>
                      </div>
                    );
                  })}
                </ul>
              </div>
            );
          })}
        </ul>
        <input onChange={e => this.setState({ newTeam: e.target.value })} value={this.state.newTeam} />
        <button onClick={this.addTeam}>Add new Team</button>
      </div>
    );
  }
}

render(<App />, document.getElementById("root"));
Khris_Al
  • 25
  • 7
  • 1
    What isn't working? – Vencovsky Feb 17 '20 at 00:27
  • I am not so clear about sending data from inputs to the state, and update it – Khris_Al Feb 17 '20 at 00:29
  • 2
    Your question is unclear and it should be focusing on one specific problem you're having. That being said, here's a lot of good questions that might help get you started. [How to update nested state properties in React](https://stackoverflow.com/q/43040721/1218980), [Correct modification of state arrays in ReactJS](https://stackoverflow.com/q/26253351/1218980), [What's the best way to update an object in an array in ReactJS?](https://stackoverflow.com/q/28121272/1218980) [Why calling react setState method doesn't mutate the state immediately?](https://stackoverflow.com/q/30782948/1218980) – Emile Bergeron Feb 17 '20 at 00:36
  • 1
    [Why can't I directly modify a component's state, really?](https://stackoverflow.com/q/37755997/1218980) [How to set state of response from axios in react](https://stackoverflow.com/q/41194866/1218980), [When to use functional setState](https://stackoverflow.com/q/48209452/1218980) – Emile Bergeron Feb 17 '20 at 00:39
  • Not that they're all relevant now, but they're all common questions I see everyday on Stack Overflow. – Emile Bergeron Feb 17 '20 at 00:39

1 Answers1

1

Something like this might help.

const newTeams = [...this.state.teams, { name: "Team3", channels: [] }]
this.setState({ teams: newTeams });

newTeams is an array than contains all the existing teams (...this.state.teams), and an additional team named Team3.

There are libraries (like immutablejs) that might be of use to you. I don't personally use them very often so I can't provide you with an exmaple, but might be something to look in to.

Edit: You mentioned you're new to React, not sure if you're also new to JS. Incase you haven't seen the ... before, it's the Spread operator.

Edit2: Re your comment about adding channels to existing teams

const newTeams = [
    ...this.state.teams,
    {
        name: "Team123",
        channels: [
            ...this.state.Team123.channels,
            { name: "NewChannel", index: 123 }
        ]
    }
];

this.setState({ team: newTeams });
Tim
  • 370
  • 5
  • 9
  • Hi, I edited my answer with a new approach, now it looks a lilttle bit better. I can add New teams but when I try to add a new Channel I have an error as follows prevState.concat is not a function, how could I add a channel to the nested array of objects? – Khris_Al Feb 17 '20 at 03:14
  • @Khris_Al I edited my answer to show adding a channel – Tim Feb 17 '20 at 03:18
  • Just saw your OP edit - You'll want to spread `prevState.teams..channels`, not the entire `prevState` – Tim Feb 17 '20 at 03:19
  • Sorry Tim, but I am no clear about your answer, could you explain me please? – Khris_Al Feb 17 '20 at 03:22
  • I am not using variables on methods, just objects, so it is confusing what you say on your previous response. – Khris_Al Feb 17 '20 at 03:39