我正在尝试在React项目中的组件加载时从api中获取数据并应用redux-thunk,但是在尝试进行异步等待api调用时出现错误uncaught Error: Actions must be plain objects. Use custom middleware for async actions.
有没有办法检查redux-thunk是否正确应用?
如何在不引发错误的情况下使用async / await?
component.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'
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>
} />
{ 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.products,
filteredColors: state.filters.colors,
filteredSizes: state.filters.sizes
});
export default connect(mapStateToProps, actionCreators)(Main);
actions.js
export const fetchProducts = async () =>
await (await fetch('https://api.github.com')).json()
configureStorejs
import { createStore, applyMiddleware } from 'redux';
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import thunk from 'redux-thunk';
import autoMergeLevel2 from 'redux-persist/lib/stateReconciler/autoMergeLevel2';
import rootReducer from './Reducers/rootReducer'; // the value from combineReducers
const persistConfig = {
key: 'root',
storage: storage,
stateReconciler: autoMergeLevel2, // see "Merge Process" section for details.
whitelist: 'language'
};
const pReducer = persistReducer(persistConfig, rootReducer);
export const store = createStore(pReducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(),
applyMiddleware(thunk)
)
export const persistor = persistStore(store);
index.js
import React from 'react'
import { render } from 'react-dom'
import App from './App'
import { Provider } from 'react-redux'
import { PersistGate } from 'redux-persist/integration/react'
import { persistor, store } from './configureStore';
const renderApp =
render(
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App />
</PersistGate>
</Provider>, root)
module.hot.accept(renderApp)
答案 0 :(得分:1)
由于您正在使用thunk
,因此可以返回一个函数
export const fetchProducts = () => async(dispatch) => {
try {
const data = await (await fetch('https://api.github.com')).json()
dispatch({ type: 'FETCH_SUCCESS', payload: {data}})
} catch (error) {
dispatch({ type: 'FETCH_FAIL', payload: {error}})
}
}