簡體   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