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

标签 javascript reactjs react-hooks react-context

我正在使用钩子(Hook)和上下文 api。我有多个操作将它们写入单独的文件中。我的问题是:在另一个文件中如何访问状态? 我使用此文件来创建我的上下文: 创建上下文.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 };
};

当我想创建上下文时,我将 actions、reducer 和默认值传递给 createContext 文件,并从中获取 Context 和 Provider。如下所示: 产品上下文.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
    );

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

最佳答案

看起来您在 Action 创建器功能中做了很多工作,这作为 reducer 的一部分更有意义。例如,而不是这样:

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 内部,您可以访问操作和状态。尝试设计您的操作,使其包含尽可能少的信息来实现您的意图。

关于javascript - 当我们使用 useReducer 时如何在操作中使用状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59239913/

相关文章:

javascript - 如何在字符之间进行匹配但不将它们包含在结果中

javascript - Firefox 中的谷歌地图 mouseevent 显示不正确的坐标

javascript - 如何在 Angular 2 Typescript 中为 FormBuilder 对象设置值

reactjs - React with TypeScript - React 检测到 ComponentName 调用的 Hooks 的顺序发生了变化

javascript - 样式化组件 onClick 旋转元素

javascript - 使用 jquery 将下拉值标记为选中

javascript - 如何同时映射3个或更多数组

javascript - Reactjs if 条件

javascript - 如何使用 https 在本地网络上构建 gatsby 开发服务?

javascript - 在 React Hooks 中有设置状态的通用方法吗?如何管理多个状态?