【问题标题】:mapDispatchToProps dispatch action working for only one functionmapDispatchToProps 调度操作仅适用于一个函数
【发布时间】:2021-08-31 23:16:36
【问题描述】:

我有两个函数只在状态的不同数组中做同样的事情

没有明显的原因,只有其中一个有效 只有 addToCart 函数有效

我不明白为什么 addToWishList 函数不起作用

首页组件

import React, { useEffect, useState } from "react";
import { makeStyles } from "@material-ui/core/styles";
import Card from "@material-ui/core/Card";
import CardActionArea from "@material-ui/core/CardActionArea";
import CardActions from "@material-ui/core/CardActions";
import CardContent from "@material-ui/core/CardContent";
import CardMedia from "@material-ui/core/CardMedia";
import Button from "@material-ui/core/Button";
import Typography from "@material-ui/core/Typography";
import { useHistory } from "react-router-dom";
import { connect } from "react-redux";
import { addToCart } from ".././redux/Shopping/shopping-action";
import { addToWishList } from ".././redux/Shopping/shopping-action";

const useStyles = makeStyles({
  root: {
    maxWidth: 345,
  },
  media: {
    height: 240,
  },
});

function Home({ addToCart }) {
  const classes = useStyles();
  const history = useHistory();
  const [products, setProducts] = useState([]);

  useEffect(() => {
    fetch("https://fakestoreapi.com/products")
      .then((res) => res.json())
      .then((json) => setProducts(json));
  }, []);
  return (
    <div>
      <h1>ALL PRODUCTS</h1>

      <div className="cards ">
        {products.map((product) => {
          return (
            <div className="card">
              <Card className={classes.root}>
                <CardActionArea
                  onClick={() => history.push(`/product/${product.id}`)}
                >
                  <CardMedia className={classes.media} image={product.image} />
                  <CardContent>
                    <Typography gutterBottom variant="h5" component="h2">
                      {product.title}
                    </Typography>
                    <Typography
                      variant="body2"
                      color="textSecondary"
                      component="h2"
                    >
                      {product.category}
                    </Typography>
                  </CardContent>
                </CardActionArea>
                <CardActions>
                  <Button
                    onClick={() => addToCart(product)}
                    size="small"
                    variant="contained"
                    color="primary"
                  >
                    ADD TO CART ????
                  </Button>
                  <Button
                    onClick={() => addToWishList(product)}
                    size="small"
                    variant="contained"
                    color="secondary"
                  >
                    Add to wish list ❤️
                  </Button>
                </CardActions>
              </Card>
            </div>
          );
        })}
      </div>
    </div>
  );
}

const mapDispatchToProps = (dispatch) => {
  return {
    addToCart: (product) => dispatch(addToCart(product)),
    addToWishList: (product) => dispatch(addToWishList(product)),
  };
};

export default connect(null, mapDispatchToProps)(Home);

shopping-action.js

import * as actionTypes from "./shopping-types";

export const addToCart = (item) => {
  return {
    type: actionTypes.ADD_TO_CART,
    payload: {
      item: item,
    },
  };
};

export const removeFromCart = (itemId) => {
  return {
    type: actionTypes.REMOVE_FROM_CART,
    payload: {
      id: itemId,
    },
  };
};

export const adjustQty = (itemId, value) => {
  return {
    type: actionTypes.ADJUST_QTY,
    payload: {
      id: itemId,
      qty: value,
    },
  };
};

export const addToWishList = (item) => {
  console.log(item);
  return {
    type: actionTypes.WISH_LIST,
    payload: {
      item: item,
    },
  };
};

shopping-reducer.js

import * as actionTypes from "./shopping-types";
const INITIAL_STATE = {
  cart: [],
  wishList: [],
};

const shopReducer = (state = INITIAL_STATE, action) => {
  console.log(action.type);
  switch (action.type) {
    case actionTypes.ADD_TO_CART:
      const item = action.payload.item;
      const isInCart = state.cart.find((item) =>
        item.id === action.payload.item.id ? true : false
      );
      return {
        ...state,
        cart: isInCart
          ? state.cart.map((item) =>
              item.id === action.payload.item.id
                ? { ...item, qty: item.qty + 1 }
                : item
            )
          : [...state.cart, { ...item, qty: 1 }],
      };
    case actionTypes.REMOVE_FROM_CART:
      return {
        ...state,
        cart: state.cart.filter((item) => item.id !== action.payload.item.id),
      };
    case actionTypes.ADJUST_QTY:
      return {
        ...state,
        cart: state.cart.map((item) =>
          item.id === action.payload.item.id
            ? { ...item, qty: action.payload.qty }
            : item
        ),
      };
    case actionTypes.WISH_LIST:
      const itemForWish = action.payload.item;
      const isInWish = state.cart.find((item) =>
        item.id === action.payload.item.id ? true : false
      );
      return {
        ...state,
        wishList: isInWish ? null : [...state.wishList, { itemForWish }],
      };
    default:
      return state;
  }
};

export default shopReducer;

shopping-types.js

export const ADD_TO_CART = "ADD_TO_CART";
export const REMOVE_FROM_CART = "REMOVE_FROM_CART";
export const ADJUST_QTY = "ADJUST_QTY";
export const WISH_LIST = "WISH_LIST";

感谢您的宝贵时间!

【问题讨论】:

    标签: reactjs redux react-redux dispatch


    【解决方案1】:

    您忘记解构由connect HOC 注入的addToWishList 属性,因此您直接调用动作创建者,而不是封装在对dispatch 的调用中的那个。

    import { connect } from "react-redux";
    import { addToCart } from ".././redux/Shopping/shopping-action";
    import { addToWishList } from ".././redux/Shopping/shopping-action"; // <-- (1) imported
    
    function Home({ addToCart }) { // <-- (3) not destructured
      ...
      return (
        <div>
          <h1>ALL PRODUCTS</h1>
    
          <div className="cards ">
            {products.map((product) => {
              return (
                <div className="card">
                  <Card className={classes.root}>
                    ...
                    <CardActions>
                      <Button
                        onClick={() => addToCart(product)}
                        ...
                      >
                        ADD TO CART ?
                      </Button>
                      <Button
                        onClick={() => addToWishList(product)} // <-- (4) non-wrapped action
                        ...
                      >
                        Add to wish list ❤️
                      </Button>
                    </CardActions>
                  </Card>
                </div>
              );
            })}
          </div>
        </div>
      );
    }
    
    const mapDispatchToProps = (dispatch) => {
      return {
        addToCart: (product) => dispatch(addToCart(product)),
        addToWishList: (product) => dispatch(addToWishList(product)), // <-- (2) injected
      };
    };
    
    export default connect(null, mapDispatchToProps)(Home);
    

    要解决这个问题,您应该解构并使用正确包装的操作。

    function Home({ addToCart }) {
    

    应该是

    function Home({ addToCart, addToWishList }) {
    

    【讨论】:

    • 我不敢相信它是如此简单.. 非常感谢!!
    猜你喜欢
    • 2019-09-13
    • 2017-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多