简体   繁体   中英

Unable to read prop in a React functional component passed via Redux

Here is the sample react functional component

const GreetingPage = (props) => {
  console.log("console log", props)

  return (
    <div>
      <h1>Hello </h1>;
    </div>
  )
}

const mapStatetoProps = (state) => ({
  user: getUser(state)
});


export default connect(mapStatetoProps)(GreetingsPage)

When I do console.log(props) it shows me the following

在此处输入图片说明

If you see there is a user object there present.

I retrieve that user from props using following

 const { user } = props
  console.log("second log", user)

And I am shown the user data

    props.user: {
  "uuid": "7dd2sdfs2-c48f-40bb-98d2-251215911d4b",
  "created_at": "2019-11-08T10:03:36.838000Z",
  "username": "joe012",
  "email": "email@gmail.com",
  "name": "Joe",
  "phone_number": null,
  "do_refresh": false,
  "plan": null,
}

Finally, when I want to get the name of the user console.log(user.name)

It says

TypeError: Cannot read property 'username' of null

What is going wrong?

In your question, you mentioned you're calling console.log(user.name) but it seems you should be calling console.log(user.username) . I assume this was just a typing error and is probably not the cause of the problem but please double check that to make sure.

Assuming that's not what's causing the problem, another possibility is the fact that the user object is retrieved asynchronously. If your component renders multiple times and the user object is null for the first render(s) and then once the user object is retrieved, the component then rerenders with the user object attached to props, then that is certainly what is happening. When you call

const { user } = props
console.log("second log", user)

It doesn't throw an error if props.user is null at first. But when you call user.username , that does throw an error since you cannot call a property on null or undefined. To fix this, you must make some kind of a check that user is not null before calling user.username . For example:

if(user) {
  console.log(user.username)
}

Or if you use ES2020 or TS 3.7+, you could use optional chaining: user?.username so that if user is falsy then it will just log undefined instead of throwing an error.

A third possibility is the get method in lodash in which you would put _.get(user, 'username') in order to ensure the user object is not null before calling an attribute on it.

Can your try this: 1.Destructuring props

const GreetingPage = ({user}) => {
console.log(user)
  return (
    <div>
      <h1>Hello </h1>;
    </div>
  )
}

const mapStatetoProps = (state) => ({
  user: getUser(state)
});


export default connect(mapStatetoProps)(GreetingsPage)

Or 2.Destructuring Child element

const GreetingPage = ({user:{username}}) => {
console.log(user)
  return (
    <div>
      <h1>Hello </h1>;
    </div>
  )
}

const mapStatetoProps = (state) => ({
  user: getUser(state)
});


export default connect(mapStatetoProps)(GreetingsPage)

Or 3.Parsing object before sending it as porps

const GreetingPage = ({user}) => {
console.log(user)
  return (
    <div>
      <h1>Hello </h1>;
    </div>
  )
}

const mapStatetoProps = (state) => ({
  user: JSON.parse(getUser(state))
});


export default connect(mapStatetoProps)(GreetingsPage)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM