Search code examples
reactjsreduxreact-hooksreact-reduxredux-toolkit

I have a problem to render product into my component, the product came from my redux store


i can save the product into my store, But I'm having trouble to rendering it in my component. the product came from api call and store in my redux store. the problem is into my component, but maybe there is a problem with my store?

//ProductDetails.jsx

  const dispatch = useDispatch();
  const { id } = useParams();
  const [product, setProduct] = useState(null);

  useEffect(() => {
    async function fetchProduct() {
      const response = await dispatch(getProduct(id));
      setProduct(response.payload);  //the app stack when i write this line

    }
    fetchProduct();
  }, [id , product]);

  return (
    <div className="details-container">
      {!product ? (
        <ClipLoader color={"#36d7b7"} loading={loading} size={35} />
      ) : (
        <div className="img-container">
          <img src={product.img} alt={product.brand} />
        </div>
      )}
    </div>
//productsSlice.jsx

export const getProduct = createAsyncThunk("products/getProduct", async (id) => {
    const prod = await productsService.getProductById(id);
    return prod
    },

        builder.addCase(getProduct.fulfilled, (state, action) => {
            state.loading = false
            state.currProduct = action.payload
            // state.error = ''
        })
);

Solution

  • try that e.g:

    //ProductDetails.jsx
      const { id } = useParams();
      const [product, setProduct] = useState(null);
    
      useEffect(() => {
        async function fetchProduct() {
          const response = await productsService.getProductById(id);
          setProduct(response.payload);
    
        }
        fetchProduct();
      }, [id , product]);
    
      return (
        <div className="details-container">
          {!product ? (
            <ClipLoader color={"#36d7b7"} loading={loading} size={35} />
          ) : (
            <div className="img-container">
              <img src={product.img} alt={product.brand} />
            </div>
          )}
        </div>
    

    Coz now you have a mix with useState and Redux.

    Pick one flow either useState or Redux. (In case of Redux you missed useSelector hook and there is no need to store product in local state)

    //example with redux
    
    /ProductDetails.jsx
      const dispatch = useDispatch();
      const { id } = useParams();
    
      useEffect(() => {
          dispatch(getProduct(id));
      }, [id]);
    
      const product = useSelector(state=>(....)) //slice with you product
      return (
        <div className="details-container">
          {!product ? (
            <ClipLoader color={"#36d7b7"} loading={loading} size={35} />
          ) : (
            <div className="img-container">
              <img src={product.img} alt={product.brand} />
            </div>
          )}
        </div>