新闻中心

React-Admin Context 更新导致路由历史警告的解决方案

2025-11-16
浏览次数:
返回列表

react-admin context 更新导致路由历史警告的解决方案

本文旨在解决在使用 React-Admin 时,通过 Context 更新全局状态导致路由历史警告的问题。文章将分析警告产生的原因,并提供通过手动创建和传递 history 对象来避免此问题的具体方法,并提供示例代码和在线沙箱进行演示。

在使用 React-Admin 开发应用时,有时需要使用 Context 来管理全局状态。当我们在组件中使用 setAppData 等函数更新 Context 中的数据时,可能会在控制台中看到 "Warning: You cannot change " 的警告。这个警告通常与 React Router 的历史对象有关,并且在 React-Admin 中,这个问题通常是因为每次 Context 更新都会导致 组件重新渲染,进而重新创建 history 对象。

问题分析

React Router 依赖于 history 对象来管理应用的路由状态。通常情况下,我们会使用 BrowserHistory,让浏览器处理路由的变化。React-Admin 内部也使用了 React Router。如果我们在 组件中没有显式地传入 history 对象,React-Admin 会自动创建一个。

当 Context 的值发生变化,React 会重新渲染依赖该 Context 的组件,包括 组件。如果没有手动传入 history,每次重新渲染都会创建一个新的 history 对象,并传递给 React Router,这会导致 React Router 抛出警告,因为 history 对象不应该被动态改变。

解决方案:手动创建并传递 History 对象

解决这个问题的方法是手动创建一个 history 对象,并将其传递给 组件。这样,即使 组件重新渲染,history 对象仍然是同一个,从而避免了警告。

具体步骤:

  1. 安装 history 库 (如果尚未安装):

    npm install history
    # 或者
    yarn add history
  2. 创建 history 对象:

    Visla Visla

    AI视频生成器,快速轻松地将您的想法转化为视觉上令人惊叹的视频。

    Visla 100 查看详情 Visla

    在你的应用入口文件 (例如 App.js 或 index.js) 中,导入 createBrowserHistory 并创建一个 history 对象。

    import { createBrowserHistory } from 'history';
    
    const history = createBrowserHistory();
  3. 将 history 对象传递给 组件:

    将创建的 history 对象作为 history prop 传递给 组件。

    import { Admin, Resource } from 'react-admin';
    import { createBrowserHistory } from 'history';
    
    const history = createBrowserHistory();
    
    const App = () => (
        <Admin dashboard={Dashboard} authProvider={authProvider} dataProvider={dataProvider} history={history}>
            <Resource name="posts" list={PostList} edit={PostEdit} create={PostCreate} />
        </Admin>
    );
    
    export default App;

示例代码:

下面是一个完整的示例,展示了如何创建和传递 history 对象:

import React, { useState, createContext } from 'react';
import { Admin, Resource } from 'react-admin';
import { createBrowserHistory } from 'history';
import { Link, Typography } from '@mui/material';

// 模拟 dataProvider 和 authProvider
const dataProvider = {
    getList: () => Promise.resolve({ data: [], total: 0 }),
    getOne: () => Promise.resolve({ data: {} }),
    getMany: () => Promise.resolve({ data: [] }),
    getManyReference: () => Promise.resolve({ data: [], total: 0 }),
    create: () => Promise.resolve({ data: {} }),
    update: () => Promise.resolve({ data: {} }),
    updateMany: () => Promise.resolve({ data: [] }),
    delete: () => Promise.resolve({ data: {} }),
    deleteMany: () => Promise.resolve({ data: [] }),
};

const authProvider = {
    login: () => Promise.resolve(),
    logout: () => Promise.resolve(),
    checkAuth: () => Promise.resolve(),
    checkError: () => Promise.resolve(),
    getPermissions: () => Promise.resolve(),
};

const AppContext = createContext({
    appData: {},
    setAppData: () => {},
});

const history = createBrowserHistory();

const App = () => {
    const [appData, setAppData] = useState({
        foo: null,
    });

    const clickHandler = (foo) => {
        const newAppData = {
            ...appData,
            foo: foo,
        };
        setAppData(newAppData);
    };

    return (
        <AppContext.Provider value={{ appData, setAppData }}>
            <Admin title="My Admin App" dashboard={() => <Dashboard clickHandler={clickHandler} />} authProvider={authProvider} dataProvider={dataProvider} history={history}>
                <Resource name="foo" />
            </Admin>
        </AppContext.Provider>
    );
};

const Dashboard = ({clickHandler}) => (
    <Link to="#" onClick={() => clickHandler("bar")}>
        Click me
    </Link>
);

export default App;

注意事项:

  • 确保在应用的根组件中创建 history 对象,并将其传递给 组件。
  • 不要在组件内部动态创建 history 对象,否则仍然会触发警告。

总结

通过手动创建和传递 history 对象,可以有效地解决 React-Admin 中 Context 更新导致路由历史警告的问题。这种方法确保了 组件始终使用同一个 history 对象,避免了 React Router 抛出警告。在开发 React-Admin 应用时,如果使用了 Context 管理全局状态,并且遇到了路由历史警告,请务必尝试这种解决方案。

以上就是React-Admin Context 更新导致路由历史警告的解决方案的详细内容,更多请关注其它相关文章!


# 是一个  # 信息关键词排名趋势  # 保险行业营销推广创新  # 湖北网站网络推广行业  # 上海网站建设公司代理  # 网站优化风格分析报告  # 涿州抖音SEO排名  # 石首装饰网站建设  # 朝阳网站建设案例套餐  # 榆阳区自媒体推广营销  # 出轨网站建设美丽  # 会在  # 是因为  # 您的  # react  # 有什么区别  # 抛出  # 如何使用  # 绑定  # 表单  # 创建一个  # 路由  # app  # 浏览器  # npm  # go  # js 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: Mac怎么锁定备忘录_Mac备忘录加密设置教程  PostgreSQL海量数据高效导入策略:Python与Django实践指南  Excel中VLOOKUP的第四个参数是干什么用的_Excel VLOOKUP第四参数作用解析  优化HTML表单样式:解决输入框焦点跳动与元素间距问题  如何使用Go和Martini动态服务解码后的图片  yy漫画网页版官方入口_yy漫画官网登录页面链接  win11 arm版怎么安装 M1/M2 Mac虚拟机安装ARM win11的方法  Win11怎么设置开机NumLock亮 Win11修改注册表InitialKeyboardIndicators值  期待已久:小米17 Ultra、小米首款NAS本月登场  Golang如何测试channel通信行为_Golang channel通信测试与分析方法  顺丰快递查单号物流信息 顺丰快递小程序查询入口  J*a中实现Go语言select通道多路复用机制  Composer的 "conflict" 字段有什么用_如何声明不兼容的包以避免依赖冲突  电脑屏幕颜色不舒服怎么办_Windows夜间模式与色彩校准教程【护眼技巧】  AO3网页版最新入口合集 Archive of Our Own在线访问指南  win11开机启动修复循环怎么办 Win11无法进入系统高级启动解决方法【修复】  外媒分析《GTA6》定价:卖100美元可以但真没必要!  Node.js CSV 数据处理:基于字段空值条件过滤整条记录的策略  铁路12306改签能改到更早的车次吗_铁路12306改签提前车次规则  XML中包含HTML标签导致解析错误? 正确嵌入非XML数据的两种方法  Win11怎么设置鼠标主按键_Win11鼠标左右键功能互换  c++中为什么推荐使用using替代typedef_c++现代化类型别名  Python中如何避免重复条件判断:利用数据结构实现动态逻辑  12306怎么选座位选到安静区_12306选座安静区域选择策略  电脑IP地址怎么查 查看本机IP地址的几种方法  Pandas DataFrame:高效添加条件计算列  韩剧圈正版入口页面_韩剧圈官网登录链接  Typer应用中动态命令行参数的解析与处理  邮政编码查询不到怎么办_邮政编码查询不到的常见原因与对策  J*aScriptWebpack优化_J*aScript构建工具实战  J*a TimerTask中HashMap意外清空的深层原因与解决方案  Node.js中HTML按钮与J*aScript函数交互的正确姿势  uc浏览器网页版极速入口 uc网页浏览器网页版流畅体验  MongoDB Aggregation:在嵌套对象数组中精确匹配ObjectId  Win11 USB传输速度慢怎么解决 Win11 USB驱动更新与设置  TikTok国际版官网直达_TikTok国际版官网直达进入在线观看  优化MinIO list_objects_v2 操作的性能瓶颈与最佳实践  AngularJS $http POST请求数据传递与Go后端接收实践  uc浏览器网页版入口 uc浏览器网页版最新网址  Golang如何实现Web接口签名验证_Golang Web接口签名校验开发方法  HuggingFaceEmbeddings中向量嵌入维度调整的限制与理解  抖音创作助手登录入口_抖音创作辅助工具官网直达  Go语言中的*string:深入理解字符串指针  BetterDiscord插件中安全更新用户简介的实践指南  Lar*el 8 多关键词数据库搜索优化实践  CSS子选择器:如何区分并样式化嵌套列表的子层级  J*aScript井字棋(Tic-Tac-Toe)核心交互逻辑实现教程  在WordPress中通过REST API获取BasicAuth保护的远程文章  提升屏幕阅读器对“m”时间单位的播报准确性:HTML与CSS组合解决方案  漫蛙2网页版漫画入口 漫蛙漫画在线官方登录 

搜索