仅在收到道具时如何渲染React(使用Redux)组件?

时间:2018-09-18 12:19:17

标签: javascript reactjs react-props

让我们假设我们有一个全状态的React组件(配置为与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));

在获取新闻和虚假新闻期间,此组件将重新渲染两次。在render方法中,我们需要检查它们是否都已加载。

只有在加载所有道具时,有什么方法可以触发渲染吗?

在理想情况下,我不想对一组道具进行详细的空/空检查。我相信只要将prop配置为required,React或Redux就应该自行执行此操作。

4 个答案:

答案 0 :(得分:2)

您可以添加生命周期方法`shouldComponentUpdate(nextProps,nextState)。

您可以添加以下方法,它应该为您解决:

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

答案 1 :(得分:1)

您可以执行以下操作:

// 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)
);

作为旁注,您可能会对recompose实用程序库的branch HOC(docs here)感兴趣。我认为这似乎是您想要的关于HOC的基本信息。

答案 2 :(得分:0)

如果要避免redux中的null和undefined值。您可以使用选择器,避免这些事情非常容易。

  const newsSelectors = (state) => {

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

export { newsSelectors };

答案 3 :(得分:0)

我认为如果您按如下所示重写render函数,就可以解决该问题。

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

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

希望对您有帮助。