所以我正在使用MERN堆栈制作一个微型电子商务应用程序,我正在使用其ID为每个卖家获取商品,因此他是唯一可以编辑或删除自己的商品的人,
在我的组件中,我从用户的redux状态获取用户的ID,然后使用该ID为每个登录的卖方获取产品。(在useEffect中) 因此获取产品取决于用户,并且始终会加载用户,并且无需在登录后获取该产品。
问题是,只有在我登录并渲染该组件后才第一次给我 TypeError:products.map不是函数。但是如果我刷新页面就可以了 因此,即使用户在那里,也看不到产品首次出现idk的原因,并且没有ID来启动提取功能。
function EditProducts() {
const { user } = useSelector(state => state.userrr);
const { loading, products } = useSelector(state => state.userProductsss);
const dispatch = useDispatch();
useEffect(() => {
console.log(user);
console.log(products);
if (!user) {
return;
} else {
let id = user._id;
dispatch(fetchUserProducts(id));
}
}, [dispatch, user]);
const deleteIt = id => {
dispatch(deleteProduct(id))
.then(res => {
toast.success(res, { position: toast.POSITION.BOTTOM_LEFT });
})
.catch(error => {
toast.error(error, {
position: toast.POSITION.BOTTOM_LEFT,
autoClose: false
});
});
};
console.log(products);
return (
<Container>
<Table striped bordered hover variant='dark'>
<thead>
<tr>
<th>category</th>
<th>Description</th>
<th>Price</th>
<th>Edit</th>
</tr>
</thead>
<tbody>
{loading && (
<tr>
<td colSpan='4'>
<Spinner animation='border' /> loading...{" "}
</td>
</tr>
)}
{!user && !loading && (
<tr>
<td colSpan='4'>Please Log in to access this page</td>
</tr>
)}
{products.map(product => (
<tr key={product._id}>
<td>{product.name}</td>
<td>{product.description}</td>
<td>${product.price}</td>
<td>
<span className='btn btn-primary mr-3'>
<UpdateProductForm
id={product._id}
name={product.name}
description={product.description}
category={product.category}
price={product.price}
numberInStock={product.numberInStock}
productImage={product.productImage}
/>
</span>
<Button className='btn btn-danger' onClick={() => deleteIt(product._id)}>
<FontAwesomeIcon icon={faTrash} />
</Button>
</td>
</tr>
))}
</tbody>
</Table>
</Container>
);
}
export default EditProducts;
这是我的减速器
const productReducer = (state = initialState, action) => {
switch (action.type) {
case FETCH_USER_PRODUCTS_STARTED:
return {
...state,
loading: true
};
case FETCH_USER_PRODUCTS_SUCCESS:
return {
...state,
loading: false,
error: null,
products: action.payload.products
};
case FETCH_USER_PRODUCTS_FAILURE:
return {
...state,
loading: false,
error: action.payload.error,
success: null
};
default:
return state;
}
};
这是动作
export const fetchUserProducts = userId => {
return dispatch => {
dispatch(fetchUserProductsStarted());
axios
.get(`/api/product/${userId}/products`)
.then(res => {
dispatch(fetchUserProductsSuccess(res.data));
})
.catch(error => {
dispatch(fetchUserProductsFailure(error.message));
});
};
};
const fetchUserProductsStarted = () => {
return {
type: FETCH_USER_PRODUCTS_STARTED
};
};
const fetchUserProductsSuccess = products => {
return {
type: FETCH_USER_PRODUCTS_SUCCESS,
payload: {
products
}
};
};
const fetchUserProductsFailure = error => {
return {
type: FETCH_USER_PRODUCTS_FAILURE,
payload: {
error
}
};
};
答案 0 :(得分:0)
所以问题在于useEffect无法确保在此处进行第一次渲染之前已加载用户数据:
const { user } = useSelector(state => state.userrr);
因此用户为空,因此根据用户ID无法获得产品。
我所做的是我再次将用户加载到组件useEffect内,以便获取用户数据。
useEffect(() => {
dispatch(loadUser());
const id = user ? user._id : null;
dispatch(fetchUserProducts(id));
}, [ dispatch, id]);