简体   繁体   中英

How to render React (with Redux) component only when props are received?

Let us assume we have a statefull React component (configured to work with Redux):

export class SomeComponent extends Component {
  state = {
    someObject: {}
  };

  componentWillMount() {
    this.props.getNews();
    this.props.getFakeNews();
  }

  render() {
    const {
      news,
      fakeNews
    } = this.props;

    if(_.isEmpty(news) || _.isEmpty(fakeNews)){
      return <div>Loading</div>
    }else{
      return <div>Here all component stuff</div>
    }
}

SomeComponent.propTypes = {
  news: PropTypes.array.isRequired,
  fakeNews: PropTypes.array.isRequired
};

export const Some = connect(
  state => ({
    news: newsSelectors.list(state),
    fakeNews: fakeNewsSelectors.list(state)
  }),
  {
    getNews,
    getFakeNEws
  }
)(withStyles(styles)(SomeComponent), withRouter(SomeComponent));

This component will re-render two times during getting news and fake news. In the render method we need to check if both of them are loaded.

Is there any way to trigger render only when all props are loaded?

In a perfect scenario I'd like to have no detailed null/empty check on the set of props. I believe React or Redux should perform this operation on its own as long the prop is configured as required .

You can add a lifecycle method `shouldComponentUpdate(nextProps, nextState).

You can add the following method and it should resolve it for you:

shouldComponentUpdate(nextProps, nextState) { 
  if (_.isEmpty(nextProps.news) || _.isEmpty(nextProps.fakeNews)) {
    return false;
  }
  return true;
}

You could do something like:

// HOC factory
function ifComponent (predicate, PlaceHolder) {
  return Component => class If extends React.Component {
    render () {
      if (predicate(this.props)) {
        return <Component {...this.props} />
      }
      return <PlaceHolder {...this.props} />
      }
    }
  }
}

// create the customHOC
const whenPropsLoaded = ifComponent(props => props.news && props.fakeNews, Loader);


// compose the two HOCs using the `compose` function in redux (simple function composition)
const News = compose(
  connect(getNewsProps),
  whenPropsLoaded(DisplayNews)
);

As a side note you may be interested in the recompose utility library bad its branch HOC ( docs here ). I think this is pretty much what you want as you seem to know about HOCs.

If you want to avoid null and undefined values from redux. You can use Selectors it was very easy to avoid those things.

  const newsSelectors = (state) => {

     if(!state.list) { *//list is null or undefined*
       return [] or {} *//your wish (Proptypes required value)*
     }
     else {
       return state.list
    }
 }

export { newsSelectors };

I think you can solve the issue if you rewrite the render function as below.

render() {
    const {
      news,
      fakeNews
    } = this.props;

    return (
        {news && fakeNews ? 
            <div>Here all component stuff</div>
        :   <div>Loading</div> }
    )
}

I hope this helps you.

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