为什么我的 React redux 状态不会导致重新渲染?
Why is my react redux state not causing a re-render?
你好,我有一个问题,当我尝试使用选择器时,我的 redux 状态没有导致重新渲染。我对 react-redux 和打字稿还很陌生。我一直在尝试 google 这个,大多数互联网线程都说这是因为你需要创建一个新对象 return 让 redux 知道状态已经改变。我已经在做了。
但是我的对象没有重新渲染,状态已更新但没有导致重新渲染。
我做错了什么?
我的 Redux reducer
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;
}
}
我的 Redux 商店
import { configureStore } from '@reduxjs/toolkit'
import { computerReducer } from './reducers/ComputerReducer'
// ...
export const store = configureStore({
reducer: {
computer: computerReducer
},
})
我selecting/using这里的状态。
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>
编辑:
这是一个使用 dispatch 来更新状态的片段。
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>
);
};
就其价值而言,您在这里使用的是一种极其过时(2019 年之前)的 Redux 风格,它最终将是您使用现代 Redux 编写的代码的 4 倍左右——尤其是与 TypeScript 结合使用时。
我强烈建议您遵循 official Redux tutorial and the TypeScript QuickStart,它会向您显示您必须设置的所有其他类型(它比您现在拥有的要少很多)。
你的问题的根源可能是意外的状态修改,这也可能发生在遗留 Redux 中的 reducer 之外 - 在现代 Redux 中,你会在你进行突变的时候立即得到一个错误 - 节省你的时间调试。所以我真的建议你切换过来,你可能会摆脱这个错误。
你好,我有一个问题,当我尝试使用选择器时,我的 redux 状态没有导致重新渲染。我对 react-redux 和打字稿还很陌生。我一直在尝试 google 这个,大多数互联网线程都说这是因为你需要创建一个新对象 return 让 redux 知道状态已经改变。我已经在做了。 但是我的对象没有重新渲染,状态已更新但没有导致重新渲染。
我做错了什么?
我的 Redux reducer
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;
}
}
我的 Redux 商店
import { configureStore } from '@reduxjs/toolkit'
import { computerReducer } from './reducers/ComputerReducer'
// ...
export const store = configureStore({
reducer: {
computer: computerReducer
},
})
我selecting/using这里的状态。
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>
编辑: 这是一个使用 dispatch 来更新状态的片段。
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>
);
};
就其价值而言,您在这里使用的是一种极其过时(2019 年之前)的 Redux 风格,它最终将是您使用现代 Redux 编写的代码的 4 倍左右——尤其是与 TypeScript 结合使用时。
我强烈建议您遵循 official Redux tutorial and the TypeScript QuickStart,它会向您显示您必须设置的所有其他类型(它比您现在拥有的要少很多)。
你的问题的根源可能是意外的状态修改,这也可能发生在遗留 Redux 中的 reducer 之外 - 在现代 Redux 中,你会在你进行突变的时候立即得到一个错误 - 节省你的时间调试。所以我真的建议你切换过来,你可能会摆脱这个错误。