Задать вопрос
ddimonn8080
@ddimonn8080

Почему props сначала undefined?

Здравствуйте, есть компонент
components/recomended/Recommended

import React, {Component} from 'react';

import CatsFilterHome from '../../containers/CatsFilterHome';
import RecommendedList from '../../containers/recommended/RecommendedList';

class Recommended extends Component {
    componentWillMount(){
        const { setProducts } = this.props;
        axios.get(`/api/products`)
            .then(response => {
                setProducts(response.data);
            });
    }

    render(){
        const {productsList, categories} = this.props.products;
        const {categoriesRelationship} = this.props;

        return (
            <div className="recommended">
                <CatsFilterHome categories={categories}/>

                <RecommendedList productsList={productsList}
                                 categories={categories}
                                 categoriesRelationship={categoriesRelationship}
                />

            </div>
        );
    }
}
export default Recommended;


есть его контейнер
containers/Recommended.js

import {connect} from 'react-redux';
import {setProducts} from '../../actions/products';
import {setFilter} from '../../actions/filter';
import Recommended from '../../components/recomended/Recommended';

function getCategoryProductRelations(categoriesRelationship){
    let newRelations = [];

    if ( categoriesRelationship !== undefined ) {
        for(let i=0;i<categoriesRelationship.length;i++) {
            let o = categoriesRelationship[i];
            if (!newRelations[o.catFilterBy]) newRelations[o.catFilterBy] = [];
            newRelations[o.catFilterBy].push(o.productID);
        }
    }
    return newRelations;
}

const mapStateToProps = ({ products }) => ({
    products: products.items,
    categoriesRelationship: getCategoryProductRelations( products.items.categoriesRelationship ),
    isReady: products.isReady,
});

const mapDispatchToProps = dispatch => ({
    setProducts: products => dispatch(setProducts(products)),
    setFilter:   filter   => dispatch(setFilter(filter)),
});

export default connect(mapStateToProps, mapDispatchToProps)(Recommended);


в Recommended выводится
containers/CatsFilterHome

import {setFilter} from "../actions/filter";
import {connect} from "react-redux";
import CatsFilterHome from '../components/CatsFilterHome';

const mapStateToProps = ({filter}, ownProps) => ({
    filterBy: filter.filterBy,
    categoriesToShow: ownProps.categories && ownProps.categories.filter(category => category.show_on_homepage == 1),
});

const mapDispatchToProps = dispatch => ({
    setFilter: filter => dispatch(setFilter(filter)),
});

export default connect(mapStateToProps, mapDispatchToProps)(CatsFilterHome);


для него компонент
components/CatsFilterHome

import React from 'react';

const CatsFilterHome = ({categoriesToShow: categories, setFilter, filterBy}) => {
    
    console.log( categories );

    const catFilterBy = filterBy ? filterBy : (categories && categories[0]['category_filter_by']);
    
    return (
        <div className="recommended__cats">
            <ul className="recommended__categoryList">
                {
                    categories && categories.map((catItem, index) => (
                        <li key={'category-key-' + index} className="recommended__categoryItem">
                            <span
                                className={'recommended__categoryItemLink' + (catFilterBy === catItem['category_filter_by'] ? ' active' : '')}
                                onClick={setFilter.bind(this, catItem['category_filter_by'])}
                            >
                                { catItem['category_name'] }
                            </span>
                        </li>
                    ))
                }
            </ul>
        </div>
    );
};

export default CatsFilterHome;


Вопрос в том что если в компоненте
CatsFilterHome
в который я передаю
categoriesToShow
вывести в консоль полученный props - он сначала undefined, а потом второй раз он уже массив.
Приходится постоянно проверять не undefined ли.
const CatsFilterHome = ({categoriesToShow: categories, setFilter, filterBy}) => {

console.log( categories );
...


Это нормальное поведение?
Можно ли избежать это повторение и проверку соответственно?
Почему так происходит?

Спасибо.
  • Вопрос задан
  • 2412 просмотров
Подписаться 1 Средний 1 комментарий
Решения вопроса 1
rockon404
@rockon404 Куратор тега React
Frontend Developer
У вас пока не пришел ответ от сервера - нет никаких категорий. Передается undefined.
Одно из многочисленных решений проблемы:
{isFetching ? <Preloader /> : this.renderContent()}

где renderContent метод отрисовывающий зависимый от данных контент вашей страницы.
Вы передаете в компонент Recommended ключ isReady(обратный isFetching), который не используете.
{isReady ? this.renderContent() : <Preloader />}

Еще по-хорошему у данных должно быть начальное состояние. В случае категорий - пустой массив.

Не ясно почему вы делаете запрос в нерекомендованном к использованию методе componentWillMount, а не используете middleware вроде redux-thunk.

Добавлять ключу элемента списка префикс 'category-key-' - бессмысленно.

Обращения вроде catItem['category_name'] так же выглядят странно.

Код:
const mapDispatchToProps = dispatch => ({
    setProducts: products => dispatch(setProducts(products)),
    setFilter:   filter   => dispatch(setFilter(filter)),
});

можно сократить до:
const mapDispatchToProps = {
  setProducts,
  setFilter,
};


Еще, лучше используйте отступ в два пробела вместо четырех. Читать код будет гораздо приятней.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
ITK academy Нижний Новгород
от 80 000 до 120 000 ₽
ITK academy Воронеж
от 50 000 до 90 000 ₽