joy
joy

Reputation: 3707

How to set default value of "props" when props.data is bind by REST API call using @connect

I am trying to set default value for prop "data" in the react component. I don't want to keep this code part of "render" function, instead I want to keep it part of constructor or some other life cycle event. However I realized that when I am keeping inside "constructor" then it throws "Cannot assign to read only property" error. However when I keep it in other lifecycle event then changes are not reflecting. Following are code for reference. Not sure what is right way to set the default value of props.data.

import React from "react";
import {connect} from 'react-redux';
import Country from "./Country";

@connect(state => ({data: state.example.data}))
export default class Countries extends  React.Component {

  constructor(props) {
    props.data = props.data || []; //This throws exception that  Cannot assign to read only property
    super(props);
  }
  componentWillMount (props) {
    console.log("componentWillMount");
    props.data = props.data || []; //This change doesn't solve the issue.
  }
  componentDidMount (props) {
    console.log("componentDidMount");
    props.data = props.data || []; //Since render function fail therefore execution flow doesn't reach here.
  }
  componentWillReceiveProps (props) {
    console.log("componentWillReceiveProps");
    props.data = props.data || []; //Since render function fail therefore execution flow doesn't reach here.
  }
  render() {

    const data = this.props.data; //This needs constructor or lifecycle method to set default value.
    //const data = this.props.data || []; //This works

    console.log("Countries  this.props "+ JSON.stringify(this.props));
    return (<div className='container'>
      <table className='table table-bordered table-striped'>
        <thead>
        <tr>
          <th>Name</th>
          <th>Capital</th>
          <th>Population</th>
          <th>Domain</th>
        </tr>
        </thead>
        <tbody>
         { data.map(country => { return (<Country key={country.name} country={country} />)})} //This throws exception as "data" is undefined at beginning. therefor need to set default value.
        </tbody>
      </table>
    </div>
    );
  };
}

Please help.

Upvotes: 0

Views: 1517

Answers (2)

iaretiga
iaretiga

Reputation: 5215

Easiest to do this in your connect function:

connect(state => ({data: state.example.data || []}))

Upvotes: 0

Ezra Chang
Ezra Chang

Reputation: 1298

React props are frozen on component creation. See https://facebook.github.io/react/blog/2015/10/07/react-v0.14.html#breaking-changes.

You must either perform your ajax call then create the component with props using results of that request, use setState to mutate the component, or clone the element.

Upvotes: 1

Related Questions