![](/img/trans.png)
[英]React Redux state not changing after calling useDispatch()
[英]React-Redux. After changing state by useDispatch, components not updating by useSelector
我有useSelectors来检查我的 App 组件是否正在更新。 第一个在 App 组件的开头,第二个在 App 返回部分。 通过单击字母,商店中的 currendElementId 更新没有问题(我通过 Redux DevTools 进行了检查)。 但是useSelectors没有更新。
我知道在 reducers 中状态应该更新为不可变的,但在createSlice中我们可能会使用可变代码,所以这不是我的情况。 (无论如何,我已经尝试制作状态副本,更改它然后发送它,但它的工作方式相同)
有我的代码:store.js
import { configureStore } from "@reduxjs/toolkit";
import pagesReducer from "./../features/Pages/pagesSlice.js";
export default configureStore({
reducer: {
pagesInfo: pagesReducer,
},
})
pageSlice.js
import { createSlice, nanoid } from "@reduxjs/toolkit";
const initialState = {
currentPage: 0,
currentElementId: null,
pages: [ // Pages
{ // Page
id: nanoid(),
lines: [
{ // Line
id: nanoid(),
aligned: "left",
content: [
{ // Symbol
id: nanoid(),
type: "symbol",
symbol: "F",
isBold: false,
isItalic: false,
isUnderlined: false,
fontSize: 18,
color: "black",
},
{ // Symbol
id: nanoid(),
type: "symbol",
symbol: "o",
isBold: false,
isItalic: false,
isUnderlined: false,
fontSize: 18,
color: "black",
},
{ // Symbol
id: nanoid(),
type: "symbol",
symbol: "r",
isBold: false,
isItalic: false,
isUnderlined: false,
fontSize: 18,
color: "black",
},
],
},
{
id: nanoid(),
aligned: "left",
content: [
{ // Image
id: nanoid(),
type: "image",
imageSrc: "./img/me and the boys.png",
width: 200,
height: 200,
},
],
},
],
},
],
}
const textSlice = createSlice({
name: "pagesInfo",
initialState,
reducers: {
changeCurrentElementID(state, action) {
state.currentElementId = action.payload;
// return {
// ...state,
// currentElementId: action.payload,
// }
}
},
})
export const { changeCurrentElementID } = textSlice.actions;
export default textSlice.reducer;
index.js
import React, { useState } from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import store from "./app/store.js";
import { Provider } from 'react-redux';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);
应用程序.js
import css from "./App.module.css";
// import BoldingTextButton from "./features/BoldingTextButton/BoldingTextButton.js";
import "./nullStyle.css";
import React, { useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { changeCurrentElementID } from "./features/Pages/pagesSlice.js";
import EnterImageButton from "./features/Pages/EnterImage/EnterImageButton.js";
import TextSizing from "./features/Pages/TextSizing/TextSizing.js";
import TextDecoration from "./features/Pages/TextDecoration/TextDecoration.js";
import TextAligning from "./features/Pages/TextAligning/TextAligning.js";
function App(props) {
console.log(useSelector(state => state.currentElementId));
const dispatch = useDispatch();
// document.addEventListener("click", event => {
// const target = event.target.closest("li")
// if (target) {
// const elementID = target.getAttribute("elementid");
// dispatch(changeCurrentElementID(elementID));
// }
// })
const changeElementID = event => {
const target = event.target.closest("li")
if (target) {
const elementID = target.getAttribute("elementid");
dispatch(changeCurrentElementID(elementID));
}
}
const GetPageContent = () => {
const rawPageLinesContent = useSelector(state => state.pagesInfo.pages[state.pagesInfo.currentPage].lines);
const currentElementID = useSelector(state => state.currentElementId);
const completedPageContent = rawPageLinesContent.map(line => {
return (
<ul key={line.id} className={css["page-line"]}>
{
line.content.map(element => {
let finalElement;
if (element.type == "symbol") {
const style = { fontSize: element.fontSize + "px" }
finalElement = (
<li onClick={changeElementID} key={element.id} elementid={element.id} className={`${css["page-line__item"]} ${css["page-line__symbol"]}`} style={style}>{element.symbol}</li>
)
if (currentElementID == element.id) {
finalElement = (
<input key={element.id} elementid={element.id} maxLength="1" className={`${css["page-line__item"]} ${css["page-line__symbol"]} ${css["page-line__choosen"]}`} style={style} value={element.symbol} />
)
}
}
else if (element.type == "image") {
finalElement = (
<li onClick={changeElementID} key={element.id} elementid={element.id} className={`${css["page-line__item"]} ${css["page-line__image"]}`}>
<img src={element.imageSrc} width={element.width} height={element.height} alt="image" />
</li>
)
}
// else if (element.type == "enter") {
// finalElement = (
// <li key={element.id} elementid={element.id} className={`${css["page-line__item"]} ${css["page-line__image"]}`}>
// <br />
// </li>
// )
// }
return finalElement;
})
}
</ul >
)
})
return completedPageContent;
}
return (
<div className={css["App"]}>
<header className={`${css['App__header']} ${css['tools']} `}>
<EnterImageButton />
<TextSizing />
<TextDecoration />
<TextAligning />
<div>{useSelector(state => state.currentElementId) || 0}</div>
</header >
<div className={`${css['App__content']} ${css['pages']} `}>
<div className={`${css['pages__item']}`} >
{GetPageContent()}
</div>
</div>
</div >
);
}
export default App;
你的选择器是错误的。
既然你有
export default configureStore({
reducer: {
pagesInfo: pagesReducer,
},
})
您的pages
切片安装为slice.pagesInfo
。
所以你需要做
useSelector(state => state.pagesInfo.currentElementId)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.