报错说我需要使用中间件,但是我已经应用了中间件
Getting an error that I need to use middleware, but I have already applied middleware
好的,我正在学习教程,我是初学者。这是我第一次接触 Redux。
这是我在应该显示网页主屏幕时遇到的错误。
Actions must be plain objects. Instead, the actual type was: 'string'. You may need to add middleware to your store setup to handle dispatching other values, such as 'redux-thunk' to handle dispatching functions. See https://redux.js.org/tutorials/fundamentals/part-4-store#middleware and https://redux.js.org/tutorials/fundamentals/part-6-async-logic#using-the-redux-thunk-middleware for examples.
我一直在到处搜索,但在我看来我正确地应用了 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
似乎是一个字符串。您不能 单独发送字符串 - 仅发送操作对象。操作是 always 对象,内部有一个 type
字段,例如 {type: 'counter/incremented'}
.
也就是说,您应该使用our official Redux Toolkit package来编写您的 Redux 代码。 Redux Toolkit 将简化您展示的所有 Redux 存储设置和缩减器逻辑。
好的,我正在学习教程,我是初学者。这是我第一次接触 Redux。
这是我在应该显示网页主屏幕时遇到的错误。
Actions must be plain objects. Instead, the actual type was: 'string'. You may need to add middleware to your store setup to handle dispatching other values, such as 'redux-thunk' to handle dispatching functions. See https://redux.js.org/tutorials/fundamentals/part-4-store#middleware and https://redux.js.org/tutorials/fundamentals/part-6-async-logic#using-the-redux-thunk-middleware for examples.
我一直在到处搜索,但在我看来我正确地应用了 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
似乎是一个字符串。您不能 单独发送字符串 - 仅发送操作对象。操作是 always 对象,内部有一个 type
字段,例如 {type: 'counter/incremented'}
.
也就是说,您应该使用our official Redux Toolkit package来编写您的 Redux 代码。 Redux Toolkit 将简化您展示的所有 Redux 存储设置和缩减器逻辑。