简体   繁体   中英

React not doing deep comparing of defaultProps

I ran into this problem when having a 2x deep object with defaultProps, and it appears if the first-level value is provided the childen element are not used as default values;

Here the Code example:

class User extends React.Component {
  render() {
    console.log('name: ', this.props.user.name);
    const {name, star} = this.props.user;
    return <div>Hello {name} - {star && '★'} </div>;
  }
}

User.defaultProps = {
    user: {name:'anonymous', star: true }
}

class UserList extends React.Component {
  render() {
    return this.props.users.map((user,i) => <User key={i} {...user} />);
  }
}

UserList.defaultProps = {
    users: [
        {user: {name:'bob', age:22}},
        {user: {age: 25}},
    ]
};

ReactDOM.render(
  <UserList />,
  document.getElementById('container')
);

In the example above, the first look will say Hello bob , the second as not expected will say Hello _ , and not Hello anonymous

Here an JsFiddle for the problem: https://jsfiddle.net/69z2wepo/98499/

Is there a way to do this? else nested default props are useless because they not even defined and 3 level deeps will couse the app to crash.

defaultProps are only used if the top level prop is undefined.

Set the defaultProps of the <User> component instead.

You cannot mutate the props if they are getting passed to the child from the parent. Iff there is no props passed by parent then you can have a default props for the child. But i strongly recommend to use state if you want the child component to change, since react goes with the concept of pure functions, Hence you state if want to set a state of your child component eg..

class User extends React.Component {
    constructor(props){
  super(props);
  this.state ={
  name:'anonymous', 
  star: true
  }
  }
  render() {
    /* console.log('name: ', this.props.user.name);
        const {name, star} = this.props.user; */
    return <div>Hello {this.state.name} - {this.state.star && '★'} </div>;
  }
}

/* User.defaultProps = {
  user: {name:'anonymous', star: true }
}
 */
class UserList extends React.Component {
  render() {
  return(
  <User/>
  )
    //return this.props.users.map((user,i) => <User key={i} {...user} />);
  }
}

/* UserList.defaultProps = {
  users: [
    {user: {name:'bob', age:22}},
    {user: {age: 25}},
  ]
}; */

ReactDOM.render(
  <UserList />,
  document.getElementById('container')
);

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