Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Default props are not available in first time render ReactJS

I am using react and redux and calling a async actions from my component lifecycle hook componentDidMount. this.props.user is updated by the the server call. I initialised with default value.

The problem is at line 1 , where 1st time the console log prints

  1. Object {name: "Test"} and second time it prints
  2. Object {user: Array[30], name: "Test"}

Why this.props doesn't have the default user array property at first time rending ?

    import React from 'react';
    import ChildComponent from './ChildComponent';
    import { fetchUsers } from "./fetchGithubUser"
    import { connect } from "react-redux"

    const styles = {
      fontFamily: 'sans-serif',
      textAlign: 'center',
      color:'green',
    };

    @connect((store) => {
      return {
        user: store.users,
      };
    })
    class App extends React.Component{

      componentDidMount() {
        this.props.dispatch(fetchUsers())
      }
      render(){

        console.log(this.props) // line 1

        return(
          <div style={styles}>
            <p> Hello World </p>
            <ChildComponent />
          </div>
        );
      }
    }
    App.defaultProps = {
      user: [1, 2, 3, 4, 5],
      name: 'Test'
    }
    export default App;
like image 457
John Doe Avatar asked Jul 23 '26 08:07

John Doe


2 Answers

So if you wish to pass default props to the component that is connected through the store using connect decorator, you would define the default props as static members of the class

@connect((store) => {
  return {
    user: store.users,
  };
})
class App extends React.Component{
  static defaultProps = {
     user: [1, 2, 3, 4, 5],
     name: 'Test'
  }
  componentDidMount() {
    this.props.dispatch(fetchUsers())
  }
  render(){

    console.log(this.props) // line 1

    return(
      <div style={styles}>
        <p> Hello World </p>
        <ChildComponent />
      </div>
    );
  }
}
export default App;

The other way to handle this would be to define initial state with the reducer

const InitialState = {
   user: [1, 2, 3, 4, 5],
   name: 'Test'
}
const myReducer = (state = InitialState, action) => {}
like image 174
Shubham Khatri Avatar answered Jul 26 '26 08:07

Shubham Khatri


In your @connect function, you pass in the user prop as coming from your store, which will overwrite default props. You can do

  return {
    user: store.users || [1, 2, 3, 4, 5],
  };

Or alternately you can pre-populate your redux store with fake user data.

like image 34
Andy Ray Avatar answered Jul 26 '26 10:07

Andy Ray



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!