Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
T treasure
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 12
    • Issues 12
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
  • Merge requests 0
    • Merge requests 0
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Operations
    • Operations
    • Incidents
    • Environments
  • Packages & Registries
    • Packages & Registries
    • Container Registry
  • Analytics
    • Analytics
    • CI/CD
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • External wiki
    • External wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • FE
  • treasure
  • Issues
  • #207

Closed
Open
Created Nov 22, 2023 by chenyu@CubiDeveloper

react 17 升级 18 注意事项

前言

react 18 版本已经放弃了对 ie 的支持,本次为 saas 后台升级记录,各业务线 c 端如需兼容 ie 浏览器可忽略版本升级。
![image.png] image__1_

image__2_

image__3_

image__4_
根据 npm 下载量可以得出推荐下列版本

"react": "18.2.0",
"react-dom": "^18.2.0",
"@types/react": "^18.2.21",
"@types/react-dom": "^18.2.14",

修改 package.json 并 npm i 或

npm i react@18.2.0 react-dom@18.2.0 @types/react@18.2.21 @types/react-dom@18.2.14

React 18 引入了一个新的 root API,它提供了更好的操作根节点的方式。新的 root API 还启用了新的并发渲染器,使开发者能够选择使用并发特性。

修改 index.tsx 入口文件 使用新的 root API

// 之前
import ReactDOM from 'react-dom';

ReactDOM.render(
  <BrowserRouter>
    <Provider store={store}>
      <ConfigProvider locale={zhCN}>
        <AliveScope> <App /></AliveScope>
      </ConfigProvider>
    </Provider>
  </BrowserRouter>,
  document.getElementById('root')
);


// 现在
import ReactDOM from 'react-dom/client';

const rootElement = document.getElementById('root')!;
if (!rootElement) throw new Error('Failed to find the root element');

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(<BrowserRouter>
  <Provider store={store}>
    <ConfigProvider locale={zhCN}>
      <AliveScope> <App /></AliveScope>
    </ConfigProvider>
  </Provider>
</BrowserRouter>);

更多修改可见官网

问题记录

m.createRoot is not a function

image__5_react17测试批处理
可以看到升级了 react 18 版本后状态更新在 setTimeout 里不会进行批处理,并且没有下图所示提示说明没有升级成功
image__6_
通过打印报错信息可以看到 react-dom的版本为17.0.2,且没有createRoot方法
image__7_
image__8_
全局搜搜项目发现 react/react-dom引用的是私有库的固定版本包,修改后重新启动项目进行测试,发现 react 18 的 setState 自动批处理特性已经打开
react18测试批处理.gif

类型 'bingint'不能作为索引类型使用

image__9_
升级到@types/react@18.2 版本后 React.Key 新增了 bigint 类型,而索引类型不支持bigint类型,将类型手动定义为 string | number 即可

隐藏问题

示例:禅道
image__10_
react17 的 setState在合成事件中为“异步执行”,是不能立刻获取到最新的状态,react18 也是如此。
但是上述代码在 react17 中 ①执行了setCanvasBgImg后在 ③能立即获取到最新的状态。在代码逻辑下,③是获取不到最新的状态的,通过查看调用堆栈情况和调用次数,updateCanvas也只执行了一次。
目前不清楚是什么问题造成该现象,在代码本身规范的前提下是不会发生此问题!
image__11_
"左侧为 react18 调用堆栈情况,右侧为 react17"

Assignee
Assign to
None
Milestone
None
Assign milestone
Time tracking