javascript - check if data has been loaded before passing as a prop react/redux
问题描述
I have an async/await api call that is made and the data is passed into my productsReducer, the problem I'm having is that the data is not loaded into the redux state when it is passed a prop into ProductsList
and therefore throws an error when it tries to filter/map the data.
adding a check to see if it is loaded is possible in ProductsList products && products
but I want to check on the Main
component first if it is loaded and if so only pass this then as a prop.
I have attempted to do so with products: state.data.products.loadng === false && state.data.products.items.data
but this always returns false
How can i check if my data is loaded before passing it as a prop?
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);
解决方案
您可以将初始状态设置为加载为真。在组件的构造函数或reducer中。在Main.js
检查加载状态是否为真的渲染函数中,并确保渲染类似加载组件的内容。
加载数据时,将加载状态设置为 false。该页面将使用数据重新呈现和呈现列表。这足够了吗?或者你想要一个例子吗?
推荐阅读
- angular - 火力基地。身份验证和托管
- c++ - 将数组打印为均匀分布的矩形
- java - 如何使用 web3j 将变量从智能合约传递到 java 项目
- c++ - 用chrono c ++与时间进行比较
- spring - Spring Cloud Config Server 无法连接到私有 git 存储库
- c# - Selenium WebDriver C#: Exception thrown finding text input element
- python - Why does it keep showing Python 3 Code Error Class Not Defined but it was defined?
- oauth - 为什么我的 GPX 上传不显示在我的 Strava 仪表板上?
- ruby-on-rails - Nginx Http redirect to https actually not working
- regex - 使用 grep + 正则表达式 linux