0

JSON

This is how the json object looks in state.

{ 
  "gender": "male",
  "name": {
    "title":"Mr."
    "first":"Mike",
    "last": "Wazowski"
  },
  ...
}

The React

const App = () => {
  const [user, setUser] = React.useState([]);

  React.useEffect(() => {
    axios
      .get("https://randomuser.me/api")
      .then((response) => {
        const info = response.data.results[0];
        setUser(info);
      })
      .catch((err) => {
        console.log(err);
      });
  }, []); 

Accessing the first lvl data works fine

  return (
    <div>
      <h1>Hello, {user.gender}</h1> 
      <h1>Hello, {user.email}</h1> 
    </div>
  )

Calling object returns Err: Objects are not valid as a React child

  return (
    <div>
      <h1>Hello, {user.name}</h1>
    </div>
  )           

Calling nested data returns TypeError: user.name undefined error

  return (
    <div>
      <h1>Hello, {user.name.first}</h1>
    </div>
  )

Why can I can access 'first level' data like gender, but not 'second-level' data like name.first?

Do I need some special syntax I'm unaware of?

4
  • There's no such thing as a "json object" Commented Jan 21, 2021 at 17:59
  • on the last block of code try {user['name']['first']}. I think it understands name and first as variables? Commented Jan 21, 2021 at 18:01
  • @Andreas thanks for the link. So I should JSON.parse(resp.data.results[0]) so that it becomes an object literal? Commented Jan 21, 2021 at 18:06
  • I'm not fluent in axios things... Check the content of response.data/response.data.results. If it's a string you might have to parse it first Commented Jan 21, 2021 at 18:08

2 Answers 2

1

I believe your errors happen at different time - you initialize your object as an empty array, so you can access fist level fields (which will be undefined), but not their fields (hence user.name undefined). Then you populate your data and user.name becomes an object and you can't just render in the DOM, so you get Objects are not valid as a React child. To solve this problem just add a null check - <h1>Hello, {user.name && user.name.first}</h1>

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

3 Comments

To build on this, you can also pass a nested empty object in to useState as the default object. Something like const [user, setUser] = React.useState({name: {first: ''}});
Should I initialize the state as 'null'? The null check did solve the problem though!
If you initialize the state as null, you'll have to null check all your fields, which is an option of course, but might be laborious. Or go with the @JimJ suggestion and use a dummy object. Whichever suites you best
0

I believe that the problem with your code is that you're trying to work with your response.data.results[0] without converting it to a JavaScript Object. That is the response from the API is a JSON and you need to convert it to a JS Object.

Can you try parsing your response.data.results[0] JSON into an Object before using it?

This should work:

const info = JSON.parse(response.data.results[0]);

4 Comments

Just tried it. Got back TypeError: user.name is undefined
Ok, can you do console.log(info) and share it with us?
Nadia's null check worked without having to Parse. I'm curious as to why that is, if you'd still like to see the console output let me know.
Oh, glad you found a solution. :)

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.