Felipe
Felipe

Reputation: 462

react js component gets state as null

I have an error while trying to pass a state as a parameter to a component

i already gave console.log and my state is getting response from api

import React, { Component } from 'react';
import api from '../../services/api';
import Products from '../Products';
export default class index extends Component {
    constructor(props){
        super(props)
            this.state={ products: [], filteredProducts:[]}

    }
    componentWillMount(){
         api.get('/products').then( result => this.setState({
            products: result.data.listProducts,
            filteredProducts: result.data.listProducts
        }))
    }
    render() {
        return (
            <>
            <Products products={this.state.filteredProducts} handleAddToCart={this.handleAddToCart}/>
            </>
        )
    }
}

My state starts as null and after consuming api it returns correctly, but the state passed to my component is null my console .log response

[]

(5) [{…}, {…}, {…}, {…}, {…}]

erros:

TypeError: Cannot read property 'map' of undefined
const productItems = this.props.productItems.map( product => (

and my component products:

import React, { Component } from 'react'
import util from '../utils';
export default class Products extends Component {
    render() {
        console.log(this.props);
        const productItems = this.props.productItems.map( product => (
            <div className="col-md-4">
            <div className = "thumbnail text-center"> 
            <a href={`#${product.id}`}  onClick={(e)=>this.props.handleAddToCard(e,product)}>
                <p>
                    {productItems.name}
                </p>
            </a>
            </div>
                <b>{util.formatCurrency(product.price)}</b>
                <button className="btn btn-primary" onClick={(e)=>this.props.handleAddToCard(e,product)}>Add to Cart</button>
            </div>
        )
        )
        return (
            <div className="row">
                {productItems}
            </div>
        )
    }
}

Upvotes: 0

Views: 239

Answers (1)

meisam
meisam

Reputation: 485

you need to move your side effect into componentDidMount and wait for component to be mounted and then does the async call and be refreshed. Meanwhile you need to have an if to prevent from loading the child component if the state is empty. so I would change your code to this.

import React, { Component } from 'react';
import api from '../../services/api';
import Products from '../Products';
export default class index extends Component {
    constructor(props){
        super(props)
            this.state={ products: [], filteredProducts:[]}

    }
    componentDidMount(){
         api.get('/products').then( result => this.setState({
            products: result.data.listProducts,
            filteredProducts: result.data.listProducts
        }))
    }
    render() {
        return (
            <>
             {this.state.ffilteredProducts.length > 0
             ?  <Products products={this.state.filteredProducts} handleAddToCart={this.handleAddToCart}/>
             : null

                }

            </>
        )
    }
}

or you can have a spinner instead of null

Upvotes: 2

Related Questions