1

I'm trying to add a state variable to another state variable.

Why am I doing this?

I'm using Firebase as a database and storing my (relatively small amount of) data through state in React. I could use different variables for each "set" of data, but I'm trying to see if it is possible using a single variable.

So, I'm creating different state variables (here: child1 and child2), and at the end storing them, or rather pushing them into another state variable (here: parent), and finally storing the state parent using firebase only.

Here's what I have tried so far:

constructor() {
    super();

    this.addMember = this.addMember.bind(this);
    this.state = {
        parent: [],
        child1: [],
        child2: []
    };

    // const child1 = [0], child2 = [0];

    // Tried using the above and below methods as well!

    // const child1 = [];
    // const child2 = [];
}


addMember(member) { // member has a property of name

    switch (member.name) {
        case `child1`:
            this.child1 = [...this.child1].push(member)  // this throws an error as it is unable to access "undefined"
            break;
        case `child2`:
            this.setState({
                child2: [...this.state.child2, member]
            })
            break; 
        default:
            throw alert("something is reeeeeeally wrong")
            // break;

    }

    let counter = {...this.state.parent}
    counter[`${member.name}`].push(this.state.child2);
    this.setState({ parent: counter})


}

The above code uses examples from other answers, which show how to store and access data within a nested object in a state:

React.js - What is the best way to add a value to an array in state

How to set a nested state in React

Accessing class variable declared in constructor in other parts of the app (React)

4
  • Your code is a bit confusing to me but if you are trying to add items to an array to store it later in the state it's a better practice to build the entire array in a local variable and then set the state once instead of do a push and setState for each item. Commented Dec 13, 2017 at 16:14
  • @Rodius hadn't thought of it that way, I'll definitely try it that way. But I still want to know if what I am trying to accomplish is possible or not. Commented Dec 13, 2017 at 16:17
  • Is it required for parent to be an array? Commented Dec 13, 2017 at 16:50
  • @TPorter Not really, anything that works really Commented Dec 13, 2017 at 16:56

2 Answers 2

1

It isn't advisable to store a state variable that is derivable directly from state or props. Instead you could store child1 and child2 as class variables and set parent state from them. Also what you are trying to do will not actually work out, since setState is async and you would need to handle it a little differently

An example of using class variable

constructor() {
    super();

    this.addMember = this.addMember.bind(this);
    this.state = {
        parent: []
    };

    this.child1 = [];
    this.child2 = [];
}


addMember(member) { // member has a property of name

    switch (member.name) {
        case `child1`:
            this.child1 = [...this.child1, member]  
            break;
        case `child2`:
            this.child2: [...this.child2, member]
            break; 
        default:
            throw alert("something is reeeeeeally wrong")
            // break;

    }

    let counter = {...this.state.parent}
    counter[`${member.name}`].push(this.child2);
    this.setState({ parent: counter})
}
Sign up to request clarification or add additional context in comments.

7 Comments

Could you share a source where I could read up on how I could handle it differently?
handling it differently meaning updating the state also into the switch component for parent. Also when updating state based on previous one, use the prevState updater function, check this stackoverflow.com/questions/42197819/…
ah. Thanks a lot! btw, what's the difference between declaring the variables as this.varname and const varname, as I had perviously?
const varname has a scope limited to the enclosing {}, and then you write using this.varname, it has a scoped to your entire class
Hey, I just tried your code, and the last but one line still returns the error TypeError: Cannot read property 'push' of undefined. Any way to fix that?
|
1

If the shape of the parent object is guaranteed (meaning something like child3 will never be added), the following would work

state = {
  parent: {
    child1: [],
    child2: []
  }
}

addMember(member) {

  this.setState(prevState => ({
    parent: prevState.parent[member.name].push(member);
  }));
  
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.