Redux ждет асинхронного действия для финского - PullRequest
0 голосов
/ 30 января 2019

Я получаю TypeError: Невозможно прочитать свойство 'map' undefined в продуктах, поскольку оно отображается перед обновлением продуктов в магазине.Поэтому я сопоставляю пустой массив.

У меня вопрос: как мне дождаться завершения асинхронного действия (fetchProducts) перед рендерингом компонента Products?

Как работает fetchProducts:

В приложении fetchProducts извлекает данные изAPI;Между тем, состояние.статус "".

Он отправляет (fetchProductsRequest ()) и изменяет состояние .status на «загрузка».

Наконец, если выборка продуктов прошла успешно, она отправляет (fetchProductsSuccess ()) и изменяет состояние.status на «success».

Products.js

import React, { Component } from 'react';
import Product from './Product';

const Products = ({ products, addToCart }) => {
  console.log(products);
  console.log(addToCart);

  return (
    <div className='img-container'>
      {products.map((product, index) => {
        let num = index + 1;
        return (
          <Product key={product.name} image={product.image} name={product.name}
            price={product.price} num={num} addToCart={addToCart} />
        );
      })}
    </div>
  );
}; 

ProductsContainer.js

import React from 'react';
import { connect } from 'react-redux';
import AddToCart from '../actions/AddToCart';
import Products from '../components/Products';

const ProductsContainer = ({ products, addToCart }) => {
  console.log(products);
  return (
    <Products products={products} addToCart={addToCart} />
  );
}

const mapStateToProps = state => ({
  products: state.products
});

const mapDispatchToProps = dispatch => ({
  AddToCart: (num, cartItem) => dispatch(AddToCart(num, cartItem))
});

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

FetchProducts.js

import FetchProductsRequest from './FetchProductsRequest';
import FetchProductsSuccess from './FetchProductsSuccess';

const FetchProducts = () => {
  return (dispatch) => {
    fetch('/products')
      .then(res => res.json())
      .then(res => dispatch(FetchProductsSuccess(res)))
      .catch(err => console.log(err));
      dispatch(FetchProductsRequest());
  }
}

export default FetchProducts;

1 Ответ

0 голосов
/ 30 января 2019

Сделать ProductsContainer компонентом класса, а не функциональным компонентом

В контейнере ProductsContainer в действии вызова componentDidMount.

В методе рендеринга ProductsContainer сделайте что-то вроде этого.

render(){
    if (!this.state.products){
        return <div>Loading</div>
    }
    return (
        <Products products={this.state.products} />
    );
}
...