Как визуализировать компонент React (с Redux) только при получении реквизитов?

77
8

Предположим, что у нас есть компонент statefull 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));

Этот компонент будет повторно отображаться два раза во время получения новостей и поддельных новостей. В методе рендеринга нам нужно проверить, загружены ли оба из них.

Есть ли способ вызвать рендеринг только при загрузке всех реквизитов?

В идеальном сценарии я бы не хотел иметь подробных проверок null/empty на наборе реквизитов. Я полагаю, что React или Redux должны выполнять эту операцию самостоятельно, так как долгое время она была настроена по мере required.

спросил(а) 2021-01-25T15:52:16+03:00 4 месяца, 4 недели назад
1
Решение
76

Вы можете добавить метод жизненного цикла 'shouldComponentUpdate (nextProps, nextState).

Вы можете добавить следующий метод, и он должен решить его для вас:

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

ответил(а) 2021-01-25T15:52:16+03:00 4 месяца, 4 недели назад
63

Вы могли бы сделать что-то вроде:

// 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.

ответил(а) 2021-01-25T15:52:16+03:00 4 месяца, 4 недели назад
45

Я думаю, вы можете решить проблему, если переписать функцию рендеринга, как показано ниже.

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

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

Я надеюсь, это поможет вам.

ответил(а) 2021-01-25T15:52:16+03:00 4 месяца, 4 недели назад
45

Если вы хотите избежать значений null и undefined из redux. Вы можете использовать Selectors, это было очень легко избежать.

  const newsSelectors = (state) => {

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

export { newsSelectors };

ответил(а) 2021-01-25T15:52:16+03:00 4 месяца, 4 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема