【问题标题】:react redux state mangment with redux toolkit使用 redux 工具包响应 redux 状态管理
【发布时间】:2021-06-20 09:16:21
【问题描述】:

link to code sandbox

我正在尝试使用 redux 无法实现它来更新状态你可以说作为初学者级别的问题我到目前为止所做的是当我调度操作它更新商店和从商店我想访问整个商店和我在电子商务网站上尝试所有这些的长度 当我调度操作时,它会更新商店,我可以看到结果,但它显示奇怪的结果,当我尝试访问长度时,我不想要这个结果是产品 ID 长度的长度,比如产品 ID 是否有 4 位数字它显示长度 4,如果我添加两次,它显示长度等于 8 这是代码

// appslice.js file
import { createSlice } from "@reduxjs/toolkit";

const appSlice = createSlice({
    name: "basket",
    initialState: {
        baskets: [],
        value: 0,
    },
    reducers: {
        incremented: (state, action) => {
            // console.log("state from appslice>>", state.baskets);
            console.log("state from appslice>>", action);
            // state.baskets += action.payload.price;
            state.baskets += action.payload;
        },
        basketvalue: (state) => {
            state.value = state.basket.length;
        },
        decremented: (state, action) => {
            state.basket -= action.payload;
        },
    },
});

export const { incremented, decremented } = appSlice.actions;
export const selectbasket = (state) => state.baskets;
export const value = (state) => state.value;

export default appSlice.reducer;
// store.js
import { configureStore } from "@reduxjs/toolkit";
import appreducer from "../appSlice";
const store = configureStore({
    reducer: appreducer,
});

export default store;
// home.js file
import Product from "./Product";
<Product
  id="12321341"
  title="title here"
  price={11.96}
  rating={5}
  image={images go here}
/>
// product.js
import React, { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { incremented, selectbasket, value } from "../redux/appSlice";
import "./product.css";

function Product({ id, title, image, price, rating }) {
    let dispatch = useDispatch();
    console.log("selectbasket", selectbasket);
    // let basketvalues = useSelector(selectbasket);
    let values = useSelector(value);
    let addtostore = () => {
        dispatch(incremented({ id, title, image, price, rating }));
    };

    return (
        <div className="product">
            {/* {console.log("valuess>>>>", values)} */}
            <div className="product__info">
                <p>{title}</p>
                <p className="product__price">
                    <small>$</small>
                    <strong>{price}</strong>
                </p>
                <div className="product__rating">
                    {/* //making Array */}
                    {Array(rating)
                        .fill()
                        .map((_, i) => (
                            <p>????</p>
                        ))}
                </div>
            </div>
            <img src={image} alt="" />
            <button onClick={addtostore}>Add to Basket</button>
        </div>
    );
}

export default Product;
// header.js here i want to show length of array in header.js
import React from "react";
import "./header.css";
import SearchIcon from "@material-ui/icons/Search";
import ShoppingCartIcon from "@material-ui/icons/ShoppingCart";
import { Link } from "react-router-dom";
import { useSelector } from "react-redux";
import { basketvalue, selectbasket } from "../redux/appSlice";

let image = window.location.origin + "/images/amazon_logo.png";

function Header() {
    let basket = useSelector(selectbasket);
    return (
        <div className="header">
            <Link to="/">
                <img className="header__logo" src={image} alt="amazon_logo" />
            </Link>
            <div className="header__search">
                <input type="text" className="header__searchInput" />
                <SearchIcon className="header__searchIcon" />
            </div>
            <div className="header__nav">
                <div className="header__option">
                    <span className="header__optionLineOne">hello, guest</span>
                    <span className="header__optionLineTwo">signin</span>
                </div>
                <div className="header__option">
                    <span className="header__optionLineOne">Return</span>
                    <span className="header__optionLineTwo">& order</span>
                </div>
                <div className="header__option">
                    <span className="header__optionLineOne">Your</span>
                    <span className="header__optionLineTwo">Prime</span>
                </div>
            </div>
            <Link to="/checkout">
                <div className="header__optionBasket ">
                    <ShoppingCartIcon />
                    <span className="header__optionLineTwo header__basketCount">
                        {console.log("basket>>>", { basket })}
                        {basket?.length}
                    </span>
                </div>
            </Link>
        </div>
    );
}

export default Header;
// checkout page here i want to access complet store with all its value
import React from "react";
import { useSelector } from "react-redux";
import { selectbasket, value } from "../redux/appSlice";
import "./checkout.css";
import Subtotal from "./subtotal";
let images = window.location.origin + "/images/amazon_ad.jpg";
function Checkout() {
    let basket = useSelector(selectbasket);
    let values = useSelector(value);
    return (
        <div className="checkout">
            {console.log("valuess>>>>", values?.length)}
            <div className="checkout_left">
                <img src={images} alt="checkout_ad" className="checkout_ad" />
                <h2 className="checkout_title">your shopping basket</h2>
                {console.log("basket from checkout >>>", basket)}
                {basket}
            </div>
            <div className="checkout_right">
                <Subtotal />
            </div>
        </div>
    );
}

export default Checkout;

【问题讨论】:

  • 如果您格式化代码,解决此类问题会容易得多 - 我建议使用 Prettier.io。由于它全部捆绑在一起并且不规则缩进,因此很难快速扫描它以查找潜在问题。
  • 好的,我正在分享代码和框链接...

标签: reactjs redux redux-toolkit


【解决方案1】:

我认为您面临的问题与减速器有关。他们有两个大问题。首先,您的两个减速器对state.basket 进行了更改,第三个对state.baskets 进行了更改。但更令人担忧的错误是将 += 和 -= 与数组值一起使用。

let arr = []
arr += {a: 4}
console.debug(arr) // Prints "[object Object]"

+= 显然没有达到您的目标(您可能想要 concat 代替)。 -= 更加棘手,因为您似乎假设它会找到一个等于有效负载的值并将其删除,但是在处理像 Object 这样的非原始值时,等式在 Javascript 中是出了名的狡猾。

我认为您需要重新考虑如何在此处尝试操作您的状态,并找出另一种使用available functions on Arrays 或将用户的购物篮更改为类似对象的数据结构来进行追加和删除的方法。一旦你让它在控制台上运行,你就可以尝试将它移植到 Redux 中(因为你的 Redux 的其余部分实际上看起来很不错)。

【讨论】:

  • 如果不这样做 += 它只显示当前状态,而我想要当前和以前的状态。
  • @vibhu 我不完全明白你在说什么,但我会在下面看看 Shubham 的建议。你需要改变 state.baskets 但你必须以在 Javascript 中实际工作的方式来做。 += 不会将对象附加到数组中,因此您必须弄清楚如何以不同的方式进行附加。
  • 我已经添加了代码沙箱的链接希望你明白我想说什么...请浏览一下链接,当你点击添加到购物篮按钮时看到变化
【解决方案2】:

由于根据您的实现,篮子应该是一个对象数组,因此您需要像处理数组一样处理加法操作,方法是推送到它而不是使用 addition operator 将对象转换为字符串和数组将两个字符串连接起来

你的实现看起来像

 incremented: (state, action) => {
        // console.log("state from appslice>>", state.baskets);
        console.log("state from appslice>>", action);
        // push payload object to the array of baskets
        state.baskets.push(action.payload);
    },

对于递减函数也需要做类似的事情。

Working sandbox

【讨论】:

  • 我已经尝试过了,但它显示错误不是功能我还在问题中添加了一个代码和框链接,当您单击添加到购物篮时,请查看右上角的更改
  • 我修改了你的 codeesandbox 并在我的答案中包含了一个工作示例
猜你喜欢
  • 1970-01-01
  • 2021-11-17
  • 2021-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-17
  • 1970-01-01
  • 2017-08-28
相关资源
最近更新 更多