讲师中心 微信公众号
AI工具推荐 视频效率加速

如何在 React 中跨页面安全传递数据(如表格行记录)

梦枫小哥_4381

梦枫小哥_4381

发布时间:2026-02-05 19:18:16

|

374人浏览过

|

来源于php中文网

原创

如何在 React 中跨页面安全传递数据(如表格行记录)

本文介绍使用 react router 与 context api 实现父子组件及跨路由页面间的数据传递,解决点击编辑按钮后 `row` 数据丢失的问题,确保 `editrecord` 页面能可靠获取原始记录。

在 React 应用中,当用户点击表格中的“编辑”按钮跳转到 /edit 页面时,若仅通过局部 useState 设置数据并立即导航(如 href 跳转),该状态将因组件卸载而丢失——这正是你遇到 record props 消失的根本原因。关键在于:状态需提升至路由级共享作用域,并配合声明式导航触发数据持久化。

✅ 正确做法:React Router + Context 管理跨页数据

1. 配置路由(App.js)

import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import ParentComponent from './ParentComponent';
import EditRecord from './EditRecord';

function App() {
  return (
    <Router>
      <Switch>
        <Route exact path="/" component={ParentComponent} />
        <Route path="/edit" component={EditRecord} />
      </Switch>
    </Router>
  );
}
export default App;

2. 创建全局数据上下文(RecordContext.js)

import React, { createContext, useState, useContext } from 'react';

const RecordContext = createContext();

export const RecordProvider = ({ children }) => {
  const [record, setRecord] = useState({});

  return (
    <RecordContext.Provider value={{ record, setRecord }}>
      {children}
    </RecordContext.Provider>
  );
};

export const useRecord = () => {
  const context = useContext(RecordContext);
  if (!context) throw new Error('useRecord must be used within RecordProvider');
  return context;
};

3. 包裹根组件(index.js 或 Root.js)

import React from 'react';
import ReactDOM from 'react-dom/client';
import { RecordProvider } from './RecordContext';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <RecordProvider>
    <App />
  </RecordProvider>
);

4. 父组件:点击时存数据 + 编程式导航(ParentComponent.js)

⚠️ 重要修正:移除 <a href> 和内联 setRecord,改用 useHistory(v5)或 useNavigate(v6)

Session Archiver Pro
Session Archiver Pro

从AI对话中提取决策、待办、知识点、偏好和风险,生成结构化记忆,支持Markdown、JSON或Obsidian笔记格式。

下载
import React from 'react';
import { useNavigate } from 'react-router-dom'; // v6 写法(推荐)
import { useRecord } from './RecordContext';

const ParentComponent = ({ data }) => {
  const navigate = useNavigate();
  const { setRecord } = useRecord();

  const handleEdit = (row) => {
    setRecord(row); // ✅ 存入全局上下文
    navigate('/edit'); // ✅ 编程式导航,不触发页面刷新
  };

  return (
    <TableBody>
      {data.map((row, index) => (
        <TableRow key={index}>
          <TableCell>
            <Button onClick={() => handleEdit(row)}>
              <EditNoteOutlined color="primary" />
            </Button>
          </TableCell>
        </TableRow>
      ))}
    </TableBody>
  );
};

export default ParentComponent;

5. 子页面:从上下文读取数据(EditRecord.js)

import React from 'react';
import { useRecord } from './RecordContext';

const EditRecord = () => {
  const { record } = useRecord();

  // ✅ 此处 record 始终为最新选中的行数据
  if (!Object.keys(record).length) {
    return <div>未选择要编辑的记录,请返回列表页</div>;
  }

  return (
    <div>
      <h2>编辑记录</h2>
      <pre>{JSON.stringify(record, null, 2)}</pre>
      {/* 此处可接入表单、API 提交等逻辑 */}
    </div>
  );
};

export default EditRecord;

⚠️ 注意事项与替代方案

  • 不要用 href 跳转 + useState:<a href> 是硬跳转,会销毁当前组件实例,本地状态必然丢失。
  • 避免 URL 参数传复杂对象:?id=123 适合简单 ID,但 row 若含嵌套结构或二进制数据,应走状态管理而非序列化到 URL。
  • 进阶场景建议:
    • 数据量大或需服务端同步 → 使用 Redux Toolkit 或 Zustand;
    • 多级嵌套路由 → 结合 useParams + 后端查询,而非前端传整个对象;
    • 需持久化(刷新不丢)→ 在 setRecord 时同步写入 sessionStorage。

通过 Context + Router 的组合,你构建了一个轻量、可维护、符合 React 思想的跨页数据流,既规避了 prop-drilling,又保证了状态生命周期与路由一致。

热门AI工具

更多
音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

相关专题

更多
js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

4456

2023.06.20

js获取当前时间
js获取当前时间

JS全称JavaScript,是一种具有函数优先的轻量级,解释型或即时编译型的编程语言;它是一种属于网络的高级脚本语言,主要用于Web,常用来为网页添加各式各样的动态功能。js怎么获取当前时间呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1355

2023.07.28

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1758

2023.08.03

js是什么意思
js是什么意思

JS是JavaScript的缩写,它是一种广泛应用于网页开发的脚本语言。JavaScript是一种解释性的、基于对象和事件驱动的编程语言,通常用于为网页增加交互性和动态性。它可以在网页上实现复杂的功能和效果,如表单验证、页面元素操作、动画效果、数据交互等。

10003

2023.08.17

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

980

2023.09.01

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2764

2023.09.04

Js中concat和push的区别
Js中concat和push的区别

Js中concat和push的区别:1、concat用于将两个或多个数组合并成一个新数组,并返回这个新数组,而push用于向数组的末尾添加一个或多个元素,并返回修改后的数组的新长度;2、concat不会修改原始数组,是创建新的数组,而push会修改原数组,将新元素添加到原数组的末尾等等。本专题为大家提供concat和push相关的文章、下载、课程内容,供大家免费下载体验。

1569

2023.09.14

js截取字符串的方法介绍
js截取字符串的方法介绍

JavaScript字符串截取方法,包括substring、slice、substr、charAt和split方法。这些方法可以根据具体需求,灵活地截取字符串的不同部分。在实际开发中,根据具体情况选择合适的方法进行字符串截取,能够提高代码的效率和可读性 。

4729

2023.09.21

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

0

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 12.3万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 1.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn