好吧,我正在学习一个教程,我是一个初学者。这是我第一次使用Redux。
这是我在应该显示网页主屏幕时遇到的错误。
操作必须是纯对象。实际类型为:"string"。您可能需要在商店设置中添加中间件来处理调度其他值,例如"redux thunk"来处理调度功能。看见https://redux.js.org/tutorials/fundamentals/part-4-store#middleware和https://redux.js.org/tutorials/fundamentals/part-6-async-logic#using-以redux-thunk中间件为例。
我一直在到处搜索,但在我看来,我正确地应用了thunk。我希望更有经验的人能够发现我的错误。非常感谢。
HomeScreen.js
import React, { useEffect } from 'react';
import {Link} from 'react-router-dom';
import { listProducts } from '../actions/productActions.js';
import { useDispatch, useSelector } from 'react-redux';
function HomeScreen() {
const productList = useSelector(state => state.productList);
const { products, loading, error} = productList;
const dispatch = useDispatch();
useEffect(() => {
dispatch(listProducts());
return () => {
//
};
}, [])
return loading? <div>Loading...</div> :
error? <div>{error}</div>:
<ul className="products">
{
products.map(product =>
<li key={product._id}>
<div className="product">
<Link to={'/product/' + product._id}>
<img className="product-image" src={product.image} alt="product" />
</Link>
<div className="product-name">
<Link to={'/product/' + product._id}>{product.name}</Link>
</div>
<div className="product-brand">{product.brand}</div>
<div className="product-price">${product.price}</div>
<div className="product-rating">{product.rating} Stars ({product.numReviews} Reviews)</div>
</div>
</li>)
}
</ul>
}
export default HomeScreen;
store.js
import { createStore, combineReducers, applyMiddleware } from 'redux';
import { productListReducer } from './reducers/productReducers.js';
import thunk from 'redux-thunk';
import * as compose from 'lodash.flowright';
const initialState = {};
const reducer = combineReducers({
productList: productListReducer,
})
const composeEnhancer = window.__REDUXDEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(reducer, initialState, composeEnhancer(applyMiddleware(thunk)));
export default store;
productActions.js
import { PRODUCT_LIST_FAIL, PRODUCT_LIST_REQUEST, PRODUCT_LIST_SUCCESS } from "../constants/productconstants.js";
import axios from "axios";
const listProducts = () => async (dispatch) => {
try {
dispatch(PRODUCT_LIST_REQUEST);
const {data} = await axios.get("/api/products");
dispatch({type: PRODUCT_LIST_SUCCESS, payload: data});
}
catch (error) {
dispatch({type: PRODUCT_LIST_FAIL, payload:error.message});
}
}
export {listProducts};
productReducers.js
import { PRODUCT_LIST_FAIL, PRODUCT_LIST_REQUEST, PRODUCT_LIST_SUCCESS } from "../constants/productconstants";
function productListReducer(state= {products: [] }, action) {
switch (action.type) {
case PRODUCT_LIST_REQUEST:
return {loading:true};
case PRODUCT_LIST_SUCCESS:
return {loading:false, products: action.payload};
case PRODUCT_LIST_FAIL:
return {loading:false, error: action.payload};
default:
return state;
}
}
export { productListReducer }
PRODUCT_LIST_REQUEST
似乎是一个字符串。不能单独调度字符串-仅用于操作对象。动作是内部有type
字段的始终对象,如{type: 'counter/incremented'}
。
也就是说,您应该使用我们的官方Redux Toolkit包来编写您的Redux代码。Redux Toolkit将简化您所展示的所有Redux存储设置和reducer逻辑。