Iterating over properties of this.state React

Iterating over properties of this.state React
0

#1

I wan to iterate over properties in this.state.

this.state looks like that:

this.state = {
            firstName: '',
            lastName: '',
            email: '',

I tried it this way:

var names = ['firstName','lastName','email'];
       alert (this.state.names[0]);

Throws error, this.state.names is undefined

I can possibly wrap firstName, lastName, email in another object:

items : {
           firstName: '',
            lastName: '',
            email: '',
}

And then use:


Object.keys(this.state.items).map(function (key) {...

But then I don’t know how to set state. Which is now:

handleData(data, name){
      this.setState({
      [name]: data,
     });

And

this.setState({
      items[name]: data,

Starts throwing an error.

Thank you for all suggestions :slight_smile:


#2

this.state is an object so iterating directly won’t work.
you could try making an array like this

var names = [this.state.firstname, this.state.lastname, this.state.email]
alert(names[0])

maybe if you were a little more specific on what you are trying to do and posted some more code i could help more.


#3

As @benjaminadk suggested state is an object.
So you can use a for each loop, or (and that’s what I generally like) using ES6 Object syntax to iterate.

Object.keys(this.state.item).map(i => alert(this.state.item[i))
 // will alert each values

You can call setState inside the map function for example:

Object.keys(this.state.item).map(
i => this.setState({ [i]: someValue }))

Please note that I use arrow function inside map so that it does not bind this.
Maybe the error you had in your function was due to the fact that you were re-binding this context.
(if your error was cannot read property state of undef it’s likely the case)


#4

I want to find a property that doesn’t have any value and trigger an even in child element. So when the user press submit button, fields that didn’t receive any value will be marked red

this.refs.property.parentMarkError();

This how my render function for parent looks like now:


render(){


         return (
           <form className="formLight" onSubmit={this.handleSubmit}>
           <Field
           name="email"
           placeholder = "Email"
           handlerFromParant={this.handleData}
           ref="email"
            />
           <Field
           name="lastName"
           placeholder = "Last Name"
           handlerFromParant={this.handleData}
           ref="lastName"
            />
           <Field
           name="firstName"
           placeholder = "First Name"
           handlerFromParant={this.handleData}
           ref="firstName"
            />
           <input className="submitButton" type="submit" value="Submit" />
           </form>
         );
       }

#5

The idea was to write something like this:

Object.keys(this.state.item).map(function (key) {
       var myitem = this.state.item[key];
       if (myitem == ''){
         this.refs.[key].parentMarkError();}
     });

#6

In your first try you have to use square brackets to access the properties, I think.

Like this:
this.state[names[0]]

Because names[0] is a string containing the name of a property of state.


#7

This function looks ok

Object.keys(this.state.item).map(function (key) {
       var myitem = this.state.item[key];
       if (myitem == ''){
         this.refs.[key].parentMarkError();}
     });

Except maybe for the binding of this.

It can be slimmed down as:

Object.keys(this.state.item).map((key) => {
       if (!this.state.item[key]){
         this.refs.[key].parentMarkError();
       }
     });

Have you tried it?

On a side note using refs is (in general) not an optimal idea in react, in the docs is explained why: refs and the dom

what you want to accomplish can be done with ease, assuming your inputs are controlled components ( ie when a user type a state change in your app, instead of letting the DOM handle it).

It’s enough to have in your state a parameter for the error and pass it to the child as prop:

this.state={
 emailError: false,
}


<Field
   {...}
    error={this.state.emailError}
/>

For example :slight_smile:


#8

Thank you very much, @Marmiz :slight_smile: That makes total sense! I am a bit new to React and child + parent relations blow my mind))


#9

Anytime!

If you have any more doubt or questions please feel free to reach me :slight_smile:

Happy coding :+1: