【问题标题】:View not showing just updated state in Redux在 Redux 中查看不显示刚刚更新的状态
【发布时间】:2021-11-26 02:50:21
【问题描述】:

我正在使用 Redux 来管理状态,但是我需要帮助才能继续前进。 这是逻辑。我正在将 state(allProducts) 中的产品价格加载到表单中。用户可以编辑任何或所有这些价格,当进行此类编辑时,updatePrice 操作会触发,并将产品及其价格存储到 updatedProducts 状态。当我登录 updatedProducts 以查看新更改时,它第一次返回空 []。但是,随后的更改显示了更新的状态 谁能帮忙解决一下?

行动:

import { UPDATE_PRICE, VIEW_ALL_PRODUCTS } from "./types";
import { productNet } from "../../../../utils/urls";
 

export const updatePrice = (price, id, allProducts) => dispatch => {
  const newArray = [...allProducts];
  newArray[id].price = price; //changing value in the new array
      dispatch({
        type: UPDATE_PRICE,
        updated_products: newArray,
      });
};

export const getAllProducts = () => async (dispatch) => {
    productNet
      .get("products/")
      .then((response) => {
          const { data } = response.data
         dispatch({
          type: VIEW_ALL_PRODUCTS,
          all_products: data,
        });
      })
      .catch((error) => {
        return;
      });
};

减速机:

import { UPDATE_PRICE, VIEW_ALL_PRODUCTS } from "../actions/types";

const initial_state = {
  allProducts: [],
  updatedProducts: [],
  priceChange: false,
};

const AdminPricingReducer = (state = initial_state, action) => {
  const { type, updated_products, all_products} = action;
  switch (type) {
    case VIEW_ALL_PRODUCTS: {
      return { ...state, allProducts: all_products};
    }
    case UPDATE_PRICE: {
      return { ...state, updatedProducts: updated_products };
    }
    default:
      return state;
  }
};

export default AdminPricingReducer;

组件:

import React, { useState, useEffect, useRef } from "react";
import { useDispatch, useSelector } from "react-redux";
import { connect } from "react-redux";
import { updatePrice, getAllProducts } from "./actions/AdminPricingAction";
const Pricing = ({
  updatePrice,
  getAllProducts,
  allProducts,
  updatedProducts,
  initial_products,
}) => {
  let targetElem = "";
  let targetDiv = "";
  const inputRefs = useRef([]);
  const editedRefs = useRef([]);
  useEffect(() => {
    getAllProducts();
  }, []);
  const handleDecrease = (index, prevPrice) => {
    let newPrice = prevPrice - 1;
    updatePrice(newPrice, index, allProducts);
  };

  const handleIncrease = (index, prevPrice) => {
    let newPrice = prevPrice + 1;
    updatePrice(newPrice, index, allProducts);
  };

  const updatePriceByTyping = (newPrice, index) => {
    updatePrice(newPrice, index, allProducts);
  };
  const showEdited = (targetDiv, i) => {
    console.log(updatedProducts); //this returned [] the first time
  };
  const handleKeyUp = (targetElem) => {
    if (targetElem) targetElem.focus();
  };

  return (
    <>
      {allProducts.length !== 0 &&
        allProducts.map((product, index) => (
          <div className="flex border-b p-6 space-between" key={index}>
            <div
              className="flex justify-between items-center w-1/2 px-4"
              key={index}
            >
              <div className="flex gap-4">
                <img
                  className="h-20 w-10 rounded-full"
                  src={product.imageUrl}
                  style={{ objectFit: "cover" }}
                  alt=""
                />
                <div>
                  <div className="text-base my-1 font-semibold mb-3">
                    {product.sku} {product.volume}
                  </div>
                  <div className="flex gap-2 items-center">
                    <div className="font-customGilroy text-sm font-medium text-center align-middle text-white">
                      <button
                        className="rounded-full py-1 px-3"
                        style={{ backgroundColor: "#F49C00" }}
                      >
                        {product.productType}
                      </button>
                    </div>
                  </div>
                </div>
              </div>
              <div className="flex gap-1">
                <button
                  className="w-6 h-6 rounded text-red-main font-bold bg-gray-200"
                  onClick={() => handleDecrease(index, product.price)}
                >
                  -
                </button>
                <input
                  key={index}
                  id={product.id}
                  value={product.price}
                  onChange={(e) => {
                    updatePriceByTyping(e.target.value, index);
                    targetDiv = editedRefs.current[index];
                    showEdited(targetDiv, index);
                  }}
                  onKeyUp={(e) => {
                    switch (e.key) {
                      case "ArrowDown":
                        targetElem =
                          inputRefs.current[
                            index === allProducts.length - 1 ? 0 : index + 1
                          ];

                        break;
                      case "ArrowUp":
                        targetElem =
                          inputRefs.current[
                            index === allProducts.length + 1 ? 0 : index - 1
                          ];

                        break;
                      default:
                        return "";
                    }
                    handleKeyUp(targetElem);
                  }}
                  ref={(el) => (inputRefs.current[index] = el)}
                  className="w-16 h-6 rounded border border-gray-300 font-customGilroy font-semibold text-grey-100 text-center not-italic text-sm py-1 px-2.5"
                />

                <button
                  className="w-6 h-6 rounded text-red-main font-bold bg-gray-200"
                  onClick={() => handleIncrease(index, product.price)}
                >
                  +
                </button>
              </div>
            </div>
            <div
              key={product.id}
              id={index}
              ref={(el) => (editedRefs.current[index] = el)}
              className="flex items-center w-1/2 px-4 invisible"
              style={{ justifyContent: "flex-end" }}
            >
              <button
                className="rounded-full py-1 px-3"
                style={{
                  backgroundColor: "#74767E",
                  color: "#FFFFFF",
                  fontSize: 14,
                  marginRight: 10,
                }}
              >
                Edited
              </button>
              <ArrowEdit />
            </div>
          </div>
        ))}
    </>
  );
};

const mapStateToProps = (state) => {
  console.log(state.PricingReducer.updatedProducts); //This logs once i make a change
  return {
    allProducts: state.PricingReducer.allProducts,
    updatedProducts: state.PricingReducer.updatedProducts,
  };
};

export default connect(mapStateToProps, {
  updatePrice,
  getAllProducts,
})(Pricing);

【问题讨论】:

  • 请澄清您的具体问题或提供更多详细信息以准确突出您的需求。正如目前所写的那样,很难准确地说出你在问什么。

标签: reactjs redux redux-thunk


【解决方案1】:

默认情况下,useEffect 在每次渲染后运行,但它也非常适合运行一些代码以响应状态更改。因为当您更新任何状态时,您需要使用特定条件调用 useEffect。

useEffect(() => {
    if (priceChange) {
        getAllProducts();
    }
}, [priceChange]);

【讨论】:

    猜你喜欢
    • 2012-04-26
    • 2018-08-07
    • 1970-01-01
    • 2020-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-22
    • 2019-07-18
    相关资源
    最近更新 更多