3

What is the right way to declare default props in react so that when I call map on a prop that is asynchronously assigned using redux I do not get an undefined error? Right now, with the following syntax I get an error when trying to assign trans_filter because data is undefined in the initial call to render.

class ContainerComponent extends React.Component {
  static defaultProps = {
    searchProps: {
      data: []
    }
  };

  constructor(props) {
    super(props);
  }

  render(){
    let trans_filter = JSON.parse(JSON.stringify(this.props.searchProps.data));
  }
}

const mapStateToProps = (state) => ({
  searchProps: state.searchProps
});

export default connect(mapStateToProps, {getTransactionsAll})(ContainerComponent);
3
  • may be stackoverflow.com/questions/38004703/… Commented Jan 7, 2017 at 13:43
  • Can you post the code for connect and the reducer? Commented Jan 7, 2017 at 13:46
  • no luck with those suggestions. Commented Jan 7, 2017 at 13:51

1 Answer 1

3

Here's how you can declare default props when using the ES6 class syntax for creating ReactJS components:

class ContainerComponent extends React.Component {
  constructor(props) {
    super(props);
  }

  render(){
    let trans_filter = JSON.parse(JSON.stringify(this.props.searchProps.data));
  }
}

ContainerComponent.defaultProps = {
  searchProps: {
    data: []
  }
};

export default ContainerComponent;

Additionally, there is another syntax for declaring defaultProps. This is a shortcut, but it will work only if your build has ES7 property initializers turned on. I assume that's why it doesn't work for you, because I see no issues with your syntax:

class ContainerComponent extends React.Component {
  static defaultProps = {
    searchProps: {
      data: []
    }
  };

  constructor(props) {
    super(props);
  }

  render() {
    let trans_filter = JSON.parse(JSON.stringify(this.props.searchProps.data));
  }
}

export default ContainerComponent;

Edit: after you shared your mapStateToProps, yes, it has something to do with Redux!

The issue is caused by your reducer. You must declare initial state shape and moreover, you must specify the initial state in each reducer. Redux will call our reducer with an undefined state for the first time. This is our chance to return the initial state of our app.

Set initial state:

const searchPropsInitialState = {
  data: []
};

Then, in your reducer when you manipulate searchProps do:

function yourReducer(state = searchPropsInitialState, action) {
  // ... switch or whatever

  return state;
}

For more details, see handling actions in the Redux docs.

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

6 Comments

Thanks. I understand everything you are saying and I've tried it all, but I must be missing something. I am using ES6, because I'm able to use the syntax I have in my sample code. When I run my app and do console.log(this.props.searchProps.data) I get undefined on the first time render is entered, hence the error I get. Why should it be undefined if I've set it to [] in my default props??? That's precisely the purpose for using default props so I don't get the error.
Does it have something to do with redux? I've edited my initial sample code to include the mapStatetoProps and connect code for redux.
@user1991118 ah, yes, it has something to do with Redux! :) I just edited my answer, please see the edit above. Please add "Redux" tag to your question too.
That was IT!!!! Hoooorray!!!! I didn't realize that I had not set the default in my reducer. I've also updated the question title and keywords to include redux. This addresses my issue, but I also want to be sure about the syntax for assigning defaultProps within my component. So basically the reason my defaultProps were being ignored is because redux takes precendence? Meaning that if the data is coming from Redux then not setting the default value in the reducer will always cause the data to show as undefined initially even if you provide a default in defaultProps??
Yes, that's correct. Actually in most of the times - for the data that you manipulate via Redux (data that holds your application store) - you don't need to declare a defaultProps inside the ReactJS component where you're using it. It depends for your specific use-case though. But anyways, now you should be able understand how the default data flow is happening. Ideally, you should want to set your initial data state in only one place.
|

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.