简体   繁体   English

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

[英]how to use state in actions when we use useReducer

I am using hooks and context api.I have multiple actions that write them into seperate file.my problem this:in another file how can I access state?我正在使用钩子和上下文 api。我有多个操作将它们写入单独的文件。我的问题是:在另一个文件中我如何访问状态? I use this file for create my contexts: createContext.js我使用这个文件来创建我的上下文: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 };
};

and when I want to create context I pass actions ,reducer and default values to createContext file and get Context and Provider from that.like this: productContext.js当我想创建上下文时,我将操作、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
    );

I can not access cart and products that are bold.how can I use them?我无法访问加粗的购物车和产品。我该如何使用它们?

It looks like you're doing a lot of work in the action creator function that would make more sense as part of the reducer.看起来您在 action creator 函数中做了很多工作,作为 reducer 的一部分更有意义。 For example, instead of this:例如,而不是这样:

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 });
};

You can do this:你可以这样做:

// 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;
  }
};

Inside the reducer is where you have access to both the action and the state.在减速器内部,您可以访问操作和状态。 Try to design your actions so that they contain the smallest amount of information possible to achieve your intention.尝试设计您的操作,以便它们包含尽可能少的信息来实现您的意图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM