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


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

Спасибо.
  • Вопрос задан
  • 2373 просмотра
Решения вопроса 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,
};


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

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

Похожие вопросы