首页 > 解决方案 > useReducer 不接受数组或状态

问题描述

无法在包含对象数组的 useReducer 钩子的初始化中传递数据(这是数组),在产品初始化中获取子组件空数组的结果。

我希望子组件中的数据与我传递的数据相同。

代码 :

import React, { createContext, useContext, useEffect, useReducer, useState } from 'react'
import faker from "faker";
import { cartReducer } from './Reducer';

export const Cart = createContext();
const Context = ({ children }) => {

    const [data, setProduct] = useState();

    useEffect(() => {
        var axios = require('axios');

        var config = {
            method: 'get',
            url: '<apicalling here>',
            headers: {
                'Authorization': 'Token xyz'
            }
        };

        axios(config)
            .then(function (response) {
                setProduct(response.data.cart[0].items);

            })
            .catch(function (error) {
                console.log(error);
            });

    }, []);


    console.warn("hello", data); //yes working, data rendering here

    const [state, dispatch] = useReducer(cartReducer, {
        products: data,
        cart: [],
    });

 
    return <Cart.Provider value={{ state, dispatch }}>{children} </Cart.Provider>;
};

export default Context;

标签: javascriptreactjsreact-redux

解决方案


发生这种情况是因为您的 reducer 在 API 调用解析之前设置了状态

并且您在 console.log 中获取了这些更新的数据,因为您正在将其更新为data状态,但减速器可以访问相同的先前数据(原因:在 API 调用解析之前减速器设置的状态

因此,您的问题的解决方案是创建一个操作,一旦您收到来自 API 的响应,就会调度您更新的 Products 值

import React, { createContext, useContext, useEffect, useReducer, useState } from 'react' import faker from "faker"; import { cartReducer } from './Reducer';

const cartReducer = (state, { type, payload = {} }) => {
switch (type) {
    case 'setProducts': {
     return {...state, products: payload};
    }
    /*
       Other actions
    */
    default: {
      // your default action
    }
  }
}

export const Cart = createContext(); 

const Context = ({ children }) => {

const [data, setProduct] = useState();

useEffect(() => {
    var axios = require('axios');

    var config = {
        method: 'get',
        url: '<apicalling here>',
        headers: {
            'Authorization': 'Token xyz'
        }
    };

    axios(config)
        .then(function (response) {
            setProduct(response.data.cart[0].items);
            dispatch({type: 'setProducts', payload: response.data.cart[0].items}) // <--- dispatch once you get data

        })
        .catch(function (error) {
            console.log(error);
        });

}, []);


console.warn("hello", data); //yes working, data rendering here

const [state, dispatch] = useReducer(cartReducer, {
    products: [],
    cart: [],
});

const value = {
   products: state.products; // <-- access it from state
   cart: state.cart
}

return <Cart.Provider value={value}>{children} </Cart.Provider>; // <--- change value here
};

export default Context;

推荐阅读