![](/img/trans.png)
[英]How to check if an element has been loaded on a page before running a script?
[英]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.