繁体   English   中英

在作为prop react / redux传递之前检查数据是否已加载

[英]check if data has been loaded before passing as a prop react/redux

我有一个异步/等待api调用,数据被传递到我的productsReducer中,我遇到的问题是,当将prop传递给ProductsList时,数据没有加载到redux状态,因此引发错误当它尝试过滤/映射数据时。

在ProductsList products && products可以添加检查以查看是否已加载,但我想先检查Main组件是否已加载,如果是,则仅通过它然后作为道具。

我尝试使用以下products: state.data.products.loadng === false && state.data.products.items.data执行此操作products: state.data.products.loadng === false && state.data.products.items.data但这始终返回false

在作为道具传递数据之前,如何检查数据是否已加载?

Main.js

import React from 'react'
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
import { TransitionGroup, CSSTransition } from "react-transition-group";
import { connect } from "react-redux";
import styled from 'styled-components'
import ScrollToTop from '../atoms/ScrollToTop'
import Header from '../Header'
import Footer from '../Footer'
import Home from '../Home'
import * as actionCreators from './actions'
import media from '../atoms/Media'
import BreadCrumbs from '../Breadcrumbs'
import Category from '../Category'
import ProductsList from '../ProductsList'
import Product from '../Product'
import Alert from '../atoms/Alert'

import { fetchProducts } from "./actions";

import { ADD_TO_CART_E, ADD_TO_CART_P } from '../atoms/translations'    

class Main extends React.Component {

  componentDidMount() {
    this.props.fetchCategories()
    this.props.fetchSubCategories()
    this.props.fetchProducts()
  }

 handleHideAlert() {
    setTimeout(() => {
      this.props.hideAlert()
    }, 1000)
  }

  render() {
    const {alert, categories, filteredColors, filteredSizes, language, products,  showAlert, subCategories} = this.props
    const e = language === 'english'
    const p = language === 'polish'
    return(
      <Router>
        <Wrap>
        {alert && <div><Alert />{this.handleHideAlert()}</div>}
        <Header e={e} p={p} categories={categories} subCategories={subCategories} language={language} />
          {/* <BreadCrumbs /> */}
          <Route style={{ flex: 1 }} render={({ location }) =>
            <TransitionGroup>
              <CSSTransition
                key={location.key}
                timeout={500}
                classNames="page"
                mountOnEnter={true}
                unmountOnExit={true}
              >
                <Switch location={location}>
                  <MainWrap>
                  <Route exact path="/" render={props => <Home e={e} p={p} categories={categories} subCategories={subCategories} products={products} language={language} {...props} />} />
                  <Route exact path="/:catId" render={props => <Category e={e} p={p} categories={categories} subCategories={subCategories} language={language} {...props} />} />
                  <Route exact path="/:catId/:subCatId" render={props => <ProductsList  e={e} p={p} filteredColors={filteredColors} filteredSizes={filteredSizes} categories={categories} subCategories={subCategories} products={products} language={language} {...props} />} />
                  <Route exact path="/:catId/:subCatId/:productId" render={props => <Product categories={categories} subCategories={subCategories} products={products} showAlert={showAlert} language={language} {...props} />} />
                  </MainWrap>
                </Switch>
              </CSSTransition>
            </TransitionGroup>
          } />
          {console.log('products',products)}
  { e ? ADD_TO_CART_E : ADD_TO_CART_P}
          <Footer />
        </Wrap>
      </Router>
    )
  }
}

const mapStateToProps = state => ({
  alert: state.ui.alert,
  language: state.language,
  categories: state.data.categories.categories,
  subCategories: state.data.subCategories.subCategories,
  products: state.data.products.loadng === false && state.data.products.items.data 
  productsLoading: state.data.products.loadng,
  filteredColors: state.filters.colors,
  filteredSizes: state.filters.sizes
});

export default connect(mapStateToProps, actionCreators)(Main);

productsReducer.js

  import {
    FETCH_PRODUCTS_REQUEST,
    FETCH_PRODUCTS_SUCCESS,
    FETCH_PRODUCTS_FAILURE
  } from '../../Constants'

  const initialState = {
    items: [],
    loading: false,
    error: null
  };

  export default function productReducer(state = initialState, action) {
    switch(action.type) {
      case FETCH_PRODUCTS_REQUEST:
        return {
          ...state,
          loading: true,
          error: null
        };

      case FETCH_PRODUCTS_SUCCESS:
        return {
          ...state,
          loading: false,
          items: action.payload
        };

      case FETCH_PRODUCTS_FAILURE:
        return {
          ...state,
          loading: false,
          error: action.payload.error,
          items: []
        };

      default:
        return state;
    }
  }

productsList.js

class ProductsList extends React.Component {

  render() {
    const { e, p, filteredColors, filteredSizes,  match, products } = this.props
    const productFilter = products && products.filter(products =>
      (
        (filteredColors.length >= 1 && filteredSizes.length < 1 && products.cat === match.params.subCatId) && filteredColors.includes(products.color) ||
        (filteredSizes.length >= 1 && filteredColors.length < 1 && products.cat === match.params.subCatId) && filteredSizes.includes(products.size) ||

        (filteredSizes.length >= 1 && filteredColors.length >= 1 && products.cat === match.params.subCatId) && filteredColors.includes(products.color) && filteredSizes.includes(products.size)) ||
        (filteredSizes.length < 1 && filteredColors.length < 1 && products.cat === match.params.subCatId)
      )
    return(
      <Section>
        <Container>
          <Grid>
            {console.log(productFilter)}

            {productFilter && productFilter.map(filteredProduct =>
              <Cell key={filteredProduct.id}>
                <ProductListCard e={e} p={p} match={match} {...filteredProduct} />
              </Cell>
            )}
          </Grid>
        </Container>
        <Filters>
          <Filter />
        </Filters>
      </Section>
    )
  }
}

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

export default connect(mapStateToProps, actionCreators)(ProductsList);

您可以设置初始状态,因为加载为true。 在组件的构造函数中或在reducer中。 Main.js的render函数中,检查加载状态是否为true,并确保呈现类似加载组件的内容。

加载数据时,将加载状态设置为false。 该页面将重新呈现并使用数据呈现列表。 这够了还是您想举个例子?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM