D
D
Dmitry2019-03-20 01:37:47
React
Dmitry, 2019-03-20 01:37:47

Why is props undefined first?

Hello, there is a component

components/recommended/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;

have his container
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);

in Recommended is displayed
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);

component for it
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;

The question is what if in the component
CatsFilterHome
to which I transfer
categoriesToShow
output the resulting props to the console - it is first undefined, and then the second time it is already an array.
Whether it is necessary to check constantly not undefined.
const CatsFilterHome = ({categoriesToShow: categories, setFilter, filterBy}) => {
console. log( categories );
...

Is this normal behavior?
Is it possible to avoid this repetition and validation respectively?
Why is this happening?
Thank you.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
Anton Spirin, 2019-03-20
@ddimonn8080

You have not yet received a response from the server - there are no categories. Passing undefined .
One of the many solutions to the problem:
where renderContent is a method that renders the data-dependent content of your page.
You are passing an isReady (reverse isFetching) key to the Recommended bean, which you are not using . In a good way, the data should have an initial state. In the case of categories, an empty array. It's not clear why you're making the request in the deprecated componentWillMount method , rather than using a middleware like redux-thunk . Adding a prefix to the list element key is pointless. Appeals seem to look strange as well. The code:

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

can be shortened to:
const mapDispatchToProps = {
  setProducts,
  setFilter,
};

Also, it's better to indent two spaces instead of four. Reading the code will be much more pleasant.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question