如何正确使用异步 React-Redux 状态
How to use async React-Redux state properly
我通过 react-redux 从 api 中获取了一些数据。我的问题是,因为它是异步的,所以我必须等待状态更新其初始值才能在应用程序中使用它们。例如我必须使用
products && products.length && products[n].img
当我尝试访问获取的数据时,语法不会出现未定义的错误。但是当我在第一次渲染时使用它们就像
products[n].img
应用程序给出了 undefined ,因为它应该是因为 redux 异步获取数据。我怎样才能绕过这些步骤,以便立即使用我想要的状态?
反应代码
import React, { useEffect } from "react";
import {useDispatch, useSelector} from 'react-redux'
import { listPoduct } from "../actions/productActions";
const Examples = () => {
const dispatch = useDispatch()
const productList = useSelector(state => state.productList)
const {loading, error, products} = productList
useEffect(()=>{
dispatch(listPoduct())
},[dispatch])
console.log(products && products.length && products[0].img)
return(
<div>
...
</div>
)
}
export default Examples
动作
export function listPoduct() {
return (dispatch) => {
const baseUrl = "/api/images"
fetch(`${baseUrl}`)
.then(res => res.json())
.then(res => {
dispatch({
type: PRODUCT_LIST_SUCCESS,
payload: res
})
})
}
}
减速机
export const productListReducer = (state = { products: [] }, action) => {
switch (action.type) {
case PRODUCT_LIST_REQUEST:
return {loading:true, products:[]}
case PRODUCT_LIST_SUCCESS:
return {loading:false, products: action.payload}
case PRODUCT_LIST_FAIL:
return {loading:false, error: action.payload}
default:
return state
}
}
商店
import {createStore, combineReducers, applyMiddleware} from 'redux'
import thunk from 'redux-thunk'
import {composeWithDevTools} from 'redux-devtools-extension'
import {productListReducer, productDetailsReducer} from './reducers/productReducer'
const reducer = combineReducers({
productList: productListReducer,
productDetails: productDetailsReducer
})
const initialState = {}
const middleware = [thunk]
const store = createStore(
reducer,
initialState,
composeWithDevTools(applyMiddleware(...middleware))
)
export default store
简短的回答是你不能。可悲的是。
您的请求是异步的,因此没有立即可用的数据。
在您的特定情况下,我的建议是有条件地呈现某种 spinner-loader(如果 loading
设置为 true)并且仅呈现加载程序。
在这种情况下,如果你将 loading
设置为 true,你将不会到达真正可以读取数据的地方(你会 render-and-return 之前)。一旦 loading
切换回 false,您现在可以在请求完成且数据位于正确位置时安全地显示数据。
这同样适用于失败状态(因为如果请求失败也没有可用数据)。
这是您修改后的代码(作为示例):
const Examples = () => {
const dispatch = useDispatch()
const productList = useSelector(state => state.productList)
const {loading, error, products} = productList
useEffect(()=>{
dispatch(listPoduct())
},[dispatch]);
if (loading) {
return (<div>Loading...</div>);
}
if (error) {
return (<div>Error: {error}</div>);
}
console.log(products && products.length && products[0].img)
return(
<div>
...
</div>
)
}
我通过 react-redux 从 api 中获取了一些数据。我的问题是,因为它是异步的,所以我必须等待状态更新其初始值才能在应用程序中使用它们。例如我必须使用
products && products.length && products[n].img
当我尝试访问获取的数据时,语法不会出现未定义的错误。但是当我在第一次渲染时使用它们就像
products[n].img
应用程序给出了 undefined ,因为它应该是因为 redux 异步获取数据。我怎样才能绕过这些步骤,以便立即使用我想要的状态?
反应代码
import React, { useEffect } from "react";
import {useDispatch, useSelector} from 'react-redux'
import { listPoduct } from "../actions/productActions";
const Examples = () => {
const dispatch = useDispatch()
const productList = useSelector(state => state.productList)
const {loading, error, products} = productList
useEffect(()=>{
dispatch(listPoduct())
},[dispatch])
console.log(products && products.length && products[0].img)
return(
<div>
...
</div>
)
}
export default Examples
动作
export function listPoduct() {
return (dispatch) => {
const baseUrl = "/api/images"
fetch(`${baseUrl}`)
.then(res => res.json())
.then(res => {
dispatch({
type: PRODUCT_LIST_SUCCESS,
payload: res
})
})
}
}
减速机
export const productListReducer = (state = { products: [] }, action) => {
switch (action.type) {
case PRODUCT_LIST_REQUEST:
return {loading:true, products:[]}
case PRODUCT_LIST_SUCCESS:
return {loading:false, products: action.payload}
case PRODUCT_LIST_FAIL:
return {loading:false, error: action.payload}
default:
return state
}
}
商店
import {createStore, combineReducers, applyMiddleware} from 'redux'
import thunk from 'redux-thunk'
import {composeWithDevTools} from 'redux-devtools-extension'
import {productListReducer, productDetailsReducer} from './reducers/productReducer'
const reducer = combineReducers({
productList: productListReducer,
productDetails: productDetailsReducer
})
const initialState = {}
const middleware = [thunk]
const store = createStore(
reducer,
initialState,
composeWithDevTools(applyMiddleware(...middleware))
)
export default store
简短的回答是你不能。可悲的是。
您的请求是异步的,因此没有立即可用的数据。
在您的特定情况下,我的建议是有条件地呈现某种 spinner-loader(如果 loading
设置为 true)并且仅呈现加载程序。
在这种情况下,如果你将 loading
设置为 true,你将不会到达真正可以读取数据的地方(你会 render-and-return 之前)。一旦 loading
切换回 false,您现在可以在请求完成且数据位于正确位置时安全地显示数据。
这同样适用于失败状态(因为如果请求失败也没有可用数据)。
这是您修改后的代码(作为示例):
const Examples = () => {
const dispatch = useDispatch()
const productList = useSelector(state => state.productList)
const {loading, error, products} = productList
useEffect(()=>{
dispatch(listPoduct())
},[dispatch]);
if (loading) {
return (<div>Loading...</div>);
}
if (error) {
return (<div>Error: {error}</div>);
}
console.log(products && products.length && products[0].img)
return(
<div>
...
</div>
)
}