[当我们使用useReducer时如何在操作中使用状态

问题描述 投票:1回答:1

我正在使用挂钩和上下文api。我有多个动作将它们写入单独的file.my问题:在另一个文件中,我如何访问状态?我使用此文件创建上下文:createContext.js

import React, { useReducer } from "react";

export default (reducer, actions, defaultValue) => {
  const Context = React.createContext();

  const Provider = ({ children }) => {
    const [state, dispatch] = useReducer(reducer, defaultValue);

    const boundActions = {};
    for (let key in actions) {
      boundActions[key] = actions[key](dispatch);
    }

    return (
      <Context.Provider value={{ state, ...boundActions }}>
        {children}
      </Context.Provider>
    );
  };
  return { Context, Provider };
};

并且当我想创建上下文时,我将action,reducer和默认值传递给createContext文件,并从中获取Context和Provider。像这样:productContext.js

    import createDataContext from "./createDataContext";
    import {storeProducts, detailProduct} from "../data";

    const productReducer = (state, action) => {
        switch (action.type) {
            case "GET_ITEM":
                return {...state, productDetail: action.productDetail};
           case "ADD_TOTALS":
            return {
                ...state,
                cartSubTotal: action.cartSubTotal,
                cartTotal: action.cartTotal,
                cartTax: action.cartTax
            };
   case "ADD_TO_CART":
            return {
                ...state,
                products: action.tempProducts,
                cart: [...state.cart, action.product]
            };
            default:
                return state;
        }
    };
    const getItem = (id) => {
        const product = **products**.find(item => item.id === id);
        return product;
    }

    const handleDetail = dispatch => (id) => {
        const productDetail = getItem(id);
        dispatch({type: "GET_ITEM", productDetail})
    };
const addToCart = dispatch => (id) => {
    let tempProducts = [...storeProducts];
    const index = tempProducts.indexOf(getItem(id));
    const product = tempProducts[index];
    product.inCart = true;
    product.count = 1;
    const price = product.price;
    product.total = price;
    dispatch({
        type: "ADD_TO_CART",
        tempProducts,
        product
    });
    const data = addTotals();
    dispatch({
        type: "ADD_TOTALS",
        cartSubTotal: data.cartSubTotal,
        cartTotal: data.cartTotal,
        cartTax: data.cartTax
    });
};
const addTotals = () => {
    let subTotal = 0;

    **cart**.map(item =>{ (subTotal += item.total)});

    const tempTax = subTotal * 0.1;
    const tax = parseFloat(tempTax.toFixed(2));
    const total = subTotal + tax;
    return {cartSubTotal: subTotal, cartTax: tax, cartTotal: total};
};
    export const {Provider, Context} = createDataContext(
        productReducer,
        {
            handleDetail,

        },
       {
        products: storeProducts,
        productDetail: detailProduct,
        cart: [],
        modalOpen: false,
        modalProduct: detailProduct,
        cartSubTotal: 0,
        cartTax: 0,
        cartTotal: 0
    );

我无法访问粗体的购物车和产品。如何使用它们?

javascript reactjs react-hooks react-context
1个回答
0
投票

看起来您在动作创建者功能中正在做很多工作,作为化简器的一部分,这将变得更加有意义。例如,代替此:

const productReducer = (state, action) => {
  switch (action.type) {
    case 'GET_ITEM':
      return { ...state, productDetail: action.productDetail };
    default:
      return state;
  }
};

const getItem = (id) => {
  // no access to state!
  const product = products.find((item) => item.id === id);
  return product;
};

const handleDetail = (dispatch) => (id) => {
  const productDetail = getItem(id);
  dispatch({ type: 'GET_ITEM', productDetail });
};

您可以这样做:

// action value
{ type: 'GET_ITEM', id: 1234 }

// reducer
const productReducer = (state, action) => {
  switch (action.type) {
    case 'GET_ITEM':
      const productDetail = state.products.find(
        (item) => item.id === action.id
      );
      return { ...state, productDetail };
    default:
      return state;
  }
};

在reducer内部,您可以访问操作和状态。尝试设计您的动作,使其包含尽可能少的信息,以实现您的意图。

© www.soinside.com 2019 - 2024. All rights reserved.