繁体   English   中英

反应-Redux。 通过 useDispatch 更改状态后,组件未通过 useSelector 更新

[英]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.

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