简体   繁体   English

为什么我的 react redux 状态不会导致重新渲染?

[英]Why is my react redux state not causing a re-render?

Hello i've an issue where my redux state not causing a re-render when i'm trying to use a selector.您好,我有一个问题,当我尝试使用选择器时,我的 redux 状态不会导致重新渲染。 I'm pretty new to react-redux and typescript.我对 react-redux 和 typescript 很陌生。 I've been trying to google this and most internet threads say it's because you need to create a new object and return that to let redux know that state has changed.我一直在尝试用谷歌搜索这个,大多数互联网线程都说这是因为你需要创建一个新对象并返回它让 redux 知道状态已经改变。 Which im already doing.我已经在做什么了。 But my object is not re-rendering, the state IS updated but not causing a rerender.但是我的对象没有重新渲染,状态已更新但不会导致重新渲染。

What am i doing wrong?我究竟做错了什么?

My Redux reducer我的 Redux 减速器


import { Computer, GraphicsCard } from "../../interfaces";

const initialState: Computer = {
    graphicsCard: null,
}


interface SelectGraphicsCardAction {
    type: "SELECT_GRAPHICSCARD";
    payload: GraphicsCard;
}

interface UnselectGraphicsCardAction {
    type: "UNSELECT_GRAPHICSCARD";
}


export type Action = SelectGraphicsCardAction | UnselectGraphicsCardAction

export const computerReducer = (state = initialState, action: Action) => {
    switch(action.type){
        case "SELECT_GRAPHICSCARD": {
            const { payload } = action;
            console.log(state, payload)

           const newState = {
                ...state,
                graphicsCard: {
                    ...state.graphicsCard,
                    ...payload
                }
            }
            //This evaluates to false
            console.log(state === newState)

            return newState
        }
        case "UNSELECT_GRAPHICSCARD": {
            return {
                ...state,
                graphicsCard: null
            }
        }
        default:
            return state;
    }

} 

My Redux Store我的 Redux 商店

import { configureStore } from '@reduxjs/toolkit'
import { computerReducer } from './reducers/ComputerReducer'
// ...

 export const store = configureStore({
  reducer: {
    computer: computerReducer
  },
})

Im selecting/using the state here.我在这里选择/使用状态。

function SelectedComputer() {
  const computer = useSelector((state: Computer) => state);
  const dispatch = useDispatch();
  const { graphicsCard } = computer;

  //Logging correct state
  console.log(computer)

  return (
    <div className="fixed top-10 right-4 bg-white rounded-t-lg">
      <p className="text-center font-bold border-b-1 border-b-black bg-gray-100 rounded-t-lg shadow-md">
        Selected Parts
      </p>
      <div className="flex flex-row">
        <CpuFill className="m-1" />
        {graphicsCard ? (
          //Not rendering this when updating state.
          <p>{graphicsCard.name}</p>
        ) : (
          <p>No Graphicscard selected!</p>
        )}
        <Trash className="flex justify-center"/>
      </div>

EDIT: Here is a snippet where am using dispatch to update the state.编辑:这是一个片段,我使用调度来更新状态。

import React, { FC } from "react";
import { Button, Card } from "react-bootstrap";
import { useDispatch } from "react-redux";
import { Component, ComputerComponent } from "../interfaces";
import { Action } from "../redux/reducers/ComputerReducer";

interface ComponentCard {
  component: Component;
  buttonText: string;
  type: string;
}

interface DomainImage {
  [key: string]: string;
}

const ComponentCard: FC<ComponentCard> = ({ component, buttonText, type }) => {
  const dispatch = useDispatch();

  const imageMap: DomainImage = {
    "inet.se": "https://cdn.inet.se/gfx/ext/226/brand-assets/inet-logo2.jpg",
    "komplett.se":
      "https://cached-images.bonnier.news/gcs/di-bilder-prod/mly/fcb28d10-158c-485b-814c-b461baa0e188.jpeg",
    "webhallen.se":
      "https://static.wikia.nocookie.net/logopedia/images/6/65/Webhallen_2021.svg/revision/latest?cb=20220420201224",
  };

  return (
    <Card className="flex flex-row items-center w-50 shadow-md mt-2 mb-2">
      <div className="flex justify-center items-center mr-3">
        <img className="h-36 w-40 p-2" src={component.imgUrl} />
      </div>
      <div className="flex-1 text-left">
        <h4 className="text-base">{component.name}</h4>
        <p>
          <span>
            ArtNr: {component.articleNumber}, Manufacturer:{" "}
            {component.manufacturer}
          </span>
        </p>
        <h4 className="absolute right-36 top-10">
          <span>{component.price} :-</span>
        </h4>
      </div>
        <Button
          color=""
          className="absolute right-5 h-10 w-20"
          onClick={() => dispatch({ type, payload: component })}
        >
          {buttonText}
        </Button>
        <a href={component.url} target="_blank" className="absolute right-5 bottom-0">
          <img
            className="w-15 h-10"
            src={imageMap[component.domainName]}
            alt={component.name}
          />
        </a>
    </Card>
  );
};

For what it's worth, you are using an extremely outdated (pre-2019) style of Redux here that will end up being about 4x the code you would write with modern Redux - especially in combination with TypeScript.值得一提的是,您在这里使用的是极其过时的(2019 年之前)风格的 Redux,最终将是您使用现代 Redux 编写的代码的 4 倍——尤其是与 TypeScript 结合使用时。

I would highly recommend you to follow the official Redux tutorial and the TypeScript QuickStart that will show you all the additional types you have to set up (it's a lot less than what you have right now).我强烈建议您遵循官方的 Redux 教程TypeScript 快速入门,它将向您展示您必须设置的所有其他类型(它比您现在拥有的要少得多)。

The source of your problem is likely an accidental state modification, which can also happen outside of reducers in legacy Redux - in modern Redux you would get an error immediately at the point where you make the mutation - saving you hours of debugging.您的问题的根源可能是意外的状态修改,这也可能发生在旧版 Redux 中的 reducer 之外 - 在现代 Redux 中,您会在进行突变时立即收到错误 - 节省您数小时的调试时间。 So I'd really recommend you just switch over and you'll probably be rid of this bug.所以我真的建议你直接切换,你可能会摆脱这个错误。

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

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