You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Router跨路由下useSelector不响应Redux状态变更求助

Redux + React Router 状态更新不渲染问题排查与修复

问题描述

我是Redux新手,正在做测试项目理解Redux和React Router的结合用法。目标是在edi1路由点击提交后,用用户输入更新Redux状态,然后在edi2路由通过useSelector显示更新后的状态。目前edi1路由里,useSelector和Redux DevTools Profiler都能看到状态正常更新,但edi2路由只渲染store的初始状态,完全不响应状态变更——就算刷新edi2标签页,状态还是初始值。

我查了React Router和Redux Toolkit的文档,React Router v5提到如果要「将路由数据和store同步并从store访问」,推荐用“深度Redux集成”,但我用的是React Router 6.4.1,不确定是否适用。

代码文件

store.js

import { configureStore } from '@reduxjs/toolkit'
import ediReducer from './ediSlice'

export const store = configureStore({
  reducer: {
    edi: ediReducer,
  },
})

ediSlice.js

import {createSlice}  from '@reduxjs/toolkit';

const initialState = {
   id:0, content: ["Hello World"],
}
export const ediSlice = createSlice({
    name: 'edi',
    initialState,
    reducers: {
        addContent: (state, action) => {
            state.content.push(action.payload);
            state.id += 1
            console.log(state.id)
        },
    }
})

export const {addContent} = ediSlice.actions;
export default ediSlice.reducer;

SendEdi.js

import { Editor } from '@tinymce/tinymce-react';
import {useRef, useState} from "react";
import {useSelector, useDispatch} from "react-redux";
import {addContent} from "../components/ediSlice.js";

export default function SendEdi() {
const ediContent = useSelector((state) => state.edi.content);
const dispatch = useDispatch()
const editorRef = useRef();
const [entryArray, setEntryArray] = useState();
 const log = () => {
    if (editorRef.current) {
        setEntryArray(editorRef.current.getContent());
        dispatch(addContent(entryArray));
        console.log("Editor Conent:", {ediContent})
    }}
 let entryEdi = <Editor
onInit={(evt, editor) => editorRef.current = editor}
apiKey='your-api-key'
disabled = {false}
inline = {false}

init={{
 selector: "#entryEdi",
 height: 500,
 menubar: false,
 placeholder: "Whats on your mind?",
 plugins: [
   'advlist', 'autolink', 'lists', 'link', 'image', 'charmap', 'preview',
   'anchor', 'searchreplace', 'visualblocks', 'code', 'fullscreen',
   'insertdatetime', 'media', 'table', 'code', 'help', 'wordcount'
 ],
 toolbar:  'undo redo | blocks | ' +
       'bold italic forecolor | alignleft aligncenter ' +
       'alignright alignjustify | bullist numlist outdent indent | ' +
       'removeformat | help',
 content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:14px }'
}}
/>

return (
<div>
   {ediContent}  
   {entryEdi}
   <button onClick={log}>Submit</button>
</div>
)
}

RecEdi.js

import {useSelector} from "react-redux";

export default function RecEdi() {
const ediContent = useSelector((state) => state.edi.content); 

    return (
        <div>
        {ediContent}
        </div>
    )
}

App.js

import {
  BrowserRouter as Router,
  Routes,
  Route
} from "react-router-dom";
import Edi1 from "./pages/edi1";
import Edi2 from "./pages/edi2";
function App() {
  return (
    <div className="App">
      <Router>
        <Routes>
          <Route path="/Edi1" element={<Edi1 />} />
          <Route path="/Edi2" element={<Edi2 />} />
        </Routes>
      </Router>
    </div>
  );
}

export default App;

edi1.js

import SendEdi from "../components/SendEdi.js";

export default function Edi1() {
  return (
    <div>
      <SendEdi />
      <h1>edi1</h1>
    </div>
  );
}

edi2.js

import RecEdi from "../components/RecEdi";

export default function Edi2() {
  return (
    <div>
      <RecEdi />
      <h1>edi2</h1>
    </div>
  );
}

index.js

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { store } from "./components/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>
);

问题根源

  1. dispatch时机错误:setEntryArray是异步更新React本地状态的操作,调用dispatch(addContent(entryArray))时,entryArray还未更新为编辑器的最新内容,第一次点击时甚至是undefined,导致store中添加了无效值。
  2. 无需深度Redux集成:React Router 6与Redux结合无需额外的深度集成配置,只要所有组件都在Provider包裹范围内即可,你的组件结构已经满足这个要求。

修复方案

修改SendEdi.js中的log函数,直接获取编辑器内容并dispatch,跳过本地state中转:

export default function SendEdi() {
const ediContent = useSelector((state) => state.edi.content);
const dispatch = useDispatch()
const editorRef = useRef();

// 移除不必要的本地state
// const [entryArray, setEntryArray] = useState();

 const log = () => {
    if (editorRef.current) {
        // 直接获取编辑器最新内容
        const latestContent = editorRef.current.getContent();
        dispatch(addContent(latestContent));
        console.log("Editor Content:", latestContent);
    }}

// 其余代码保持不变...
}

修改后,点击提交按钮时会直接将编辑器的最新内容发送到store,edi1和edi2路由的useSelector都会正确响应状态变更,edi2页面就能显示更新后的内容了。

内容的提问来源于stack exchange,提问作者CreativeDesign

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 01:46:47