1

So I just started with react and I was going through one of the videos about "Handling Dynamic content in react).

So our main goal is to display three boxes using map function when we click on a button.

We Initially created State Object like this

state = {
    person: [
    {name: "Rohit", age: 24},
    {name: "Hariom", age: 23},
    {name: "Vaibhav", age: 58}
  ],
  someOtherState: "Untouched state",
  showPerson: false
}

And then we tried something like this for conditional and mapping

 render() {

    let person = null;

    if (this.state.showPerson) {
      person = (
        <div>
          {this.state.person.map(Person => {
            return <Person
            name={Person.name}
            age={Person.age} />
          })}
          </div>
     );
    }

Followed by this

return (

  <div className="App">
        <h1> Hi I am react App</h1>
        <button onClick={this.togglerPersonHandler}>Button</button>
        {person}
    </div>
      );
   }
}

Now, When I click on a button it throws following error (three times)

index.js:2178 Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.

Check your code at App.js:54.
    in App (at index.js:7)

and

index.js:2178 The above error occurred in the <div> component:
    in div (at App.js:52)
    in div (at App.js:63)
    in App (at index.js:7)

Consider adding an error boundary to your tree to customize error handling behavior.

What am I doing wrong here? (THe togglerPersonHandler simply changes the value of someOtherState). Do let me know my mistake and fix.

1
  • Can you post the code for togglerPersonHandler() method? Commented Apr 11, 2018 at 17:31

2 Answers 2

4

Issue is in this part:

{this.state.person.map(Person => { return <Person .....})

Don't forgot that, we write jsx that is syntactic sugar, it will get converted into:

React.createElement(type, props, children)

Type should be either a string for html tags, or react component.

So in your case, you are using Person as an argument to arrow function means its value will be each object of the this.state.persons array. At the same time you are rendering <Person />, and Person is an object, not a valid type, that's why you are getting error:

React.createElement: type is invalid

Solution will be, if (Person is a react component, you defined somewhere), use a different name:

<div>
    {
        this.state.person.map(el => (
            <Person
                key={el.name}
                name={el.name}
                age={el.age} />
            )
        )
    }
</div>

Also assign a unique key to each element.

Sign up to request clarification or add additional context in comments.

5 Comments

Hey, That does solve my problem. I have one more questions though If I do something like this ` this.state.person.map(el => { it doesn't work but when I do something like this ' this.state.person.map(el => ( ' it works. I know I am missing something, Can you please also tell the difference?
sorry, i didn't see any diff both are same, can you please explain more
this.state.person.map(el => { does not work but this.state.person.map(el => ( works. I can see the difference between { and ( but can you tell me why it does not work with this {
The video tutorial I am following, My instructor did something like this: imgur.com/a/bIpqb
because these are two ways of using arrow function one is () => {return ....} and () => (), with {} return is required and with () whatever you write inside that will be returned :)
0

I Agree with @Mayank Shukla. Although a simpler, less complicated way of doing this would be

    render() {
    let person = this.state.person.map(per => <Person key={per.name} name={per.name} age={per.age}/>);

    return (  <div className="App">
        <h1> Hi I am react App</h1>
        <button onClick={this.togglerPersonHandler}>Button</button>
        {this.state.showPerson ? person : ''}
    </div>);
}

}

Comments

Your Answer

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