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



让我们假设我们有一个有状态的 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));

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

有没有办法仅在加载所有道具时才触发渲染?

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

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

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

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

你可以做这样的事情:

// 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实用程序库感兴趣,它branchHOC (文档在这里(。我认为这几乎是您想要的,因为您似乎对 HOC 有所了解。

如果要避免 redux 中的空值和未定义值。您可以使用选择器,很容易避免这些事情。

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

我认为如果您按如下方式重写渲染函数,您可以解决问题。

render() {
const {
news,
fakeNews
} = this.props;
return (
{news && fakeNews ? 
<div>Here all component stuff</div>
:   <div>Loading</div> }
)
}

我希望这对你有所帮助。

最新更新