为什么我的产品有这个功能是空的?
Why my products are empty with this function?
在控制台中,它向我显示了一条警告:
传递给 selectId
实现的实体返回未定义。您可能应该提供自己的 selectId
实现。传递的实体:(2) [{...}, {...}] selectId
实现:item => item._id。
我错过了什么?
我尝试调用产品:
const products = useSelector(productSelectors.selectIds)
import { createSlice, createEntityAdapter, createAsyncThunk } from "@reduxjs/toolkit";
import axios from "axios";
//Fetch the businesses to show in the home page
export const fetchProducts = createAsyncThunk(
'products/fetchProducts',
async (id, { dispatch }) => {
return axios.get(`https://api-test-carrinho.herokuapp.com/product/business/${id}`
).then(resp => {
dispatch(addProducts(resp.data))
})
}
)
const productsAdapter = createEntityAdapter({
selectId: (item) => item._id
});
const productsSlice = createSlice({
name: "products",
initialState: productsAdapter.getInitialState({ loading: false }),
reducers: {
/* addProduct: productsAdapter.addOne, */
addProducts: productsAdapter.setAll
},
extraReducers: {
[fetchProducts.pending](state){
state.loading = true
},
[fetchProducts.fulfilled](state, { payload }){
state.loading = false
productsAdapter.setAll(state, payload)
}
}
});
export default productsSlice.reducer;
export const { /* addProduct, */addProducts } = productsSlice.actions;
export const productSelectors = productsAdapter.getSelectors(
(state) => state.products
);
export const {
selectById: selectProductById,
selectAll: selectAllProducts
} = productSelectors;
根据Redux Documentation,useSelector
应该是一个函数:
import React from 'react'
import { useSelector } from 'react-redux'
export const CounterComponent = () => {
const counter = useSelector((state) => state.counter)
return <div>{counter}</div>
}
所以,也许这会对你有所帮助:
const products = useSelector(state => state./* however your store is implemented */productSelectors.selectIds)
未定义 ID
我能够复制你的错误信息
The entity passed to the selectId
implementation returned undefined.
在第一个错误实例中,我在控制台中看到的是三个产品的数组。它试图在该数组 上找到._id
属性 。它认为 array
是单个实体而不是实体数组。然后它试图在 3
和 0
.
这样的数字上找到 ._id
属性
这里发生的事情是它将 your response 视为产品对象的字典,但事实并非如此。我们只需要查看 .data
属性 即可找到产品。
这就是令人困惑的地方,但您实际上需要 resp.data.data
而不是 resp.data
。 axios
响应有一个 .data
属性,其中包含 JSON。然后在你的 JSON 里面你有自己的 .data
属性.
Thunk 问题
我修复该问题后,addProducts
成功将产品添加到状态。但是fetchProducts.fulfilled
再往下还有问题。你会得到一个错误
TypeError: Cannot convert undefined or null to object
因为您完成的操作的payload
是undefined
。
使用 createAsyncThunk
你实际上不需要 dispatch
thunk 的任何东西。您需要做的是 return
您想要作为 fetchProducts.fulfilled
操作的 payload
的数据。
export const fetchProducts = createAsyncThunk(
"products/fetchProducts",
async (id) => {
return axios
.get(`https://api-test-carrinho.herokuapp.com/product/business/${id}`)
.then((resp) => resp.data.data);
}
);
在控制台中,它向我显示了一条警告:
传递给 selectId
实现的实体返回未定义。您可能应该提供自己的 selectId
实现。传递的实体:(2) [{...}, {...}] selectId
实现:item => item._id。
我错过了什么?
我尝试调用产品:
const products = useSelector(productSelectors.selectIds)
import { createSlice, createEntityAdapter, createAsyncThunk } from "@reduxjs/toolkit";
import axios from "axios";
//Fetch the businesses to show in the home page
export const fetchProducts = createAsyncThunk(
'products/fetchProducts',
async (id, { dispatch }) => {
return axios.get(`https://api-test-carrinho.herokuapp.com/product/business/${id}`
).then(resp => {
dispatch(addProducts(resp.data))
})
}
)
const productsAdapter = createEntityAdapter({
selectId: (item) => item._id
});
const productsSlice = createSlice({
name: "products",
initialState: productsAdapter.getInitialState({ loading: false }),
reducers: {
/* addProduct: productsAdapter.addOne, */
addProducts: productsAdapter.setAll
},
extraReducers: {
[fetchProducts.pending](state){
state.loading = true
},
[fetchProducts.fulfilled](state, { payload }){
state.loading = false
productsAdapter.setAll(state, payload)
}
}
});
export default productsSlice.reducer;
export const { /* addProduct, */addProducts } = productsSlice.actions;
export const productSelectors = productsAdapter.getSelectors(
(state) => state.products
);
export const {
selectById: selectProductById,
selectAll: selectAllProducts
} = productSelectors;
根据Redux Documentation,useSelector
应该是一个函数:
import React from 'react'
import { useSelector } from 'react-redux'
export const CounterComponent = () => {
const counter = useSelector((state) => state.counter)
return <div>{counter}</div>
}
所以,也许这会对你有所帮助:
const products = useSelector(state => state./* however your store is implemented */productSelectors.selectIds)
未定义 ID
我能够复制你的错误信息
The entity passed to the
selectId
implementation returned undefined.
在第一个错误实例中,我在控制台中看到的是三个产品的数组。它试图在该数组 上找到._id
属性 。它认为 array
是单个实体而不是实体数组。然后它试图在 3
和 0
.
._id
属性
这里发生的事情是它将 your response 视为产品对象的字典,但事实并非如此。我们只需要查看 .data
属性 即可找到产品。
这就是令人困惑的地方,但您实际上需要 resp.data.data
而不是 resp.data
。 axios
响应有一个 .data
属性,其中包含 JSON。然后在你的 JSON 里面你有自己的 .data
属性.
Thunk 问题
我修复该问题后,addProducts
成功将产品添加到状态。但是fetchProducts.fulfilled
再往下还有问题。你会得到一个错误
TypeError: Cannot convert undefined or null to object
因为您完成的操作的payload
是undefined
。
使用 createAsyncThunk
你实际上不需要 dispatch
thunk 的任何东西。您需要做的是 return
您想要作为 fetchProducts.fulfilled
操作的 payload
的数据。
export const fetchProducts = createAsyncThunk(
"products/fetchProducts",
async (id) => {
return axios
.get(`https://api-test-carrinho.herokuapp.com/product/business/${id}`)
.then((resp) => resp.data.data);
}
);