React Awesome
tip
- 专门功能选择专业组件 - Headless 配合 UI 组件达到更为理想的结果
- react-table
- react-hook-form
- floatingui
- 选择样式与组件独立的 UI 库
- tailwindcss+daisyui
- rewindui/rewindui
- 避免选择绑定了功能的组件
- antd
- 选择组件库的考虑维度
- 前端/后端 - C 端/B 端
- 信息密度
- 支持平台 - Web/移动端
- 使用支持 ESM 的库
常用依赖
# 状态管理 - jotai
npm add zustand immer use-immer
# UI
npm add classnames
npm add react-icons
npx tailwindcss init -p # tailwindcss
# API
npm add react-query # generic
npm add urql # gql
# 组件
# blueprintjs - v4 发布后不需要 x2 包
npm add @blueprintjs/core @blueprintjs/select @blueprintjs/datetime @blueprintjs/popover2
# 如果需要展示大量数据
npm add @blueprintjs/table
# 移动端样式组件
npm add tailwind-mobile
# 交互
npm add react-virtual # 虚拟滚动
npm add @headlessui/react # 纯功能组件
# 路由
npm add react-router-dom
# 数据
npm add react-hook-form
npm add react-table
# 工具
npm add date-fns lodash-es react-fast-compare
通用 UI 组件
- tailwindcss+daisyui
- 如果开发人员能力足够
- 如果想要完全控制样式
- 如果想要做自己的产品
- TailwindCSS
- palantir/blueprint
- CSS 样式定义 + React 封装组件
- 很多组件都可以直接 HTML + CSS 类定义达到效果 - 非常清晰明了
- npm 包含源码 - IDE 能直接看到组件源码
@blueprintjs/select
- 多功能 select 组件
- 不控制样式,以逻辑为主
- radix-ui/primitives
- by WorkOS
- Slot 组件 - asChild 时使用 child 组件进行渲染,传递所有 props
- nextui-org/nextui
- 与 vercel 无关
- rsuite/rsuite
- 各方面神似 AntD - 但比 AntD 轻的多
- ant-design/ant-design
- 1.3MB
- @ant-design/icons
- dayjs
- rx-
- @antdesign/cssinjs
- mui-org/material-ui - Material Design 风格
- 如果选择 MD 风格则非常匹配
- 完成程度和成熟度远远高于 antd
- 组件非常多,支持高度样式自定义
- geist-org/geist-ui
- 类似 vercel 的设计风格
- arco-design/arco-design
- 字节跳动
- DouyinFE/semi-design
- 抖音前端
- 较多的 AntD 内容
- 公司相关设计风格组件库
- carbon-design-system/carbon
- IBM
- SAP/openui5
- microsoft/fluentui - 微软风格
- pinterest/gestalt - pinterest
- JetBrains/ring-ui - Jetbrains 产品系列
- 例如 Youtrack
- 查询用的组件功能非常强大 - Query Assist
- Youtrack 的 Issuse 搜索过滤
- segmentio/evergreen - Segment
- elastic/eui
- 组件丰富
- 集成了 ACE 编辑器、Markdown 编辑器、DND
- Search、Suggest、Expression 等查询组件功能强大
- carbon-design-system/carbon
- 其他风格
- cloudscape-design/components
- design system for the cloud
- mantinedev/mantine
- emotion
- CSS in JS
npm install @mantine/core @mantine/hooks @mantine/form @mantine/dates dayjs @mantine/notifications @mantine/prism @mantine/tiptap @tabler/icons-react @tiptap/react @tiptap/extension-link @tiptap/starter-kit @mantine/dropzone @mantine/carousel embla-carousel-react @mantine/spotlight @mantine/modals @mantine/nprogress @emotion/react
- core
- @floating-ui
- @radix-ui
- 524.6kB
- grommet/grommet
- primefaces/primereact
- DevExpress/devextreme-reactive
- 功能强大的 Scheduler
- uiwjs/uiw
- 国产
- 包含一些特殊组件 - PIN 码、评分、日历
- markdown 编辑器、高德地图、百度地图
- uiwjs/province-city-china - 省市区数据
- cloudscape-design/components
- 不再维护/不活跃
- ebs-integrator/ebs-design
- supabase/ui
- rebassjs/rebass
- 基于 theme-ui 和 styled-system 的基础组件
- 很多样式都通过 props 控制
- 如果喜欢这样的还不如选择 tailwindcss 更加规范实用
移动端 UI 组件
专用 UI 组件
- Select/Tag/Input
- react-tags/react-tags
- npm:react-tag-input
- react-dnd
- yairEO/tagify
- rc-select
- jedwatson/react-select
- @floating-ui/core, @emotion/react, stylis
- 功能完善的 select 组件
- 通过 emotion 控制样式 - 如果没有使用 emotion 建议避免使用
- react-autosuggest
- downshift-js/downshift
- autocomplete, combobox, select dropdown
- useCombobox
- useMultipleSelection
- useSelect
- react-tags/react-tags
- calendar
- fullcalendar/fullcalendar
- 功能最为强大的日历组件 - 支持 React 绑定
- wojtekmaj/react-calendar
- fullcalendar/fullcalendar
- flow/diagram
- dnd
- clauderic/dnd-kit
- react-dnd/react-dnd
- atlassian/react-beautiful-dnd - 拖放
- bokuweb/react-rnd - Resize & Drag
- 实现类似窗口的效果
- react-draggable+bokuweb/re-resizable
- react-grid-layout/react-draggable
- 非常简单的拖动组件
- 传递 style, className, onMouseDown, onMouseUp, onTouchStart, onTouchEnd 给 child 实现功能
- style: transform: translate(538.5px, 22px);
- className: react-draggable react-draggable-dragging react-draggable-dragged
- child 需要能 ref
- 组件
- Draggable - 包含基础状态,可受控的拖拽组件
- DraggableCore - 无状态功能组件
- react-grid-layout/react-resizable
- 简单的 resize 组件
- 组件
- ResizableBox - 维护 div 状态实现简单 resize -
<div {...props} />
- Resizable - 无状态基础功能组件
- ResizableBox - 维护 div 状态实现简单 resize -
- SortableJS/Sortable
- react-dropzone/react-dropzone
- Query Builder
- layout
- react-grid-layout/react-grid-layout
- 动态网格布局组件
- react-draggable+react-grid-layout/react-resizable
- nomcopter/react-mosaic
- tiling window manager
- zzarcon/react-cristal
- simple window manager
- https://dev.to/jbdemonte/create-a-window-manager-with-react-3mak
- Create a window manager with React
- react-div-100vh
- 移动端屏高问题
- react-grid-layout/react-grid-layout
- scrollbar/container/affix
- react-scroll
- 实现滚动到自定义位置
- okonet/react-scroll-sync
- 多个 scroll 同步
- KingSora/OverlayScrollbars
- react-scroll
- Dashboard/Panel/Splitter/Layout
- devbookhq/splitter
- 切分面板
- tremorlabs/tremor
- Apache-2.0
- build dashboards
- 构建 Dashboard
- devbookhq/splitter
- Toast/Interactive/Notification
- react-hot-toast
- 12kB/4.7kB
- goober 2.5kB/1.3kB
- css-in-js alternative
- goober 2.5kB/1.3kB
- 12kB/4.7kB
- iamhosseindhv/notistack
- for Material UI
- react-toastify
- 需要 import css
- react-hot-toast
- Tree
- carousel/image zoom/view
- malaman/react-image-zoom
- 放大一块区域
- rpearce/react-medium-image-zoom
- 类似 medium 的点击图片放大
- xiaolin/react-image-gallery
- 图片浏览
- guonanci/react-images-viewer
- 55kB
- nolimits4web/swiper
- express-labs/pure-react-carousel
- leandrowd/react-responsive-carousel
- ~30kB
- react-easy-swipe +5kB
- akiran/react-slick
- https://alvarotrigo.com/blog/react-carousels/
- malaman/react-image-zoom
- image editor/crop/rotate/scale/processing
- DominicTobias/react-image-crop
- ISC, TS
- 图片裁剪
- ValentinH/react-easy-crop
- MIT, TS
- 图片裁剪
- scaleflex/filerobot-image-editor
- MIT, JS
- 基于 react-konva
- 功能非常高级
- swimmingkiim/react-image-editor
- React + Konva / image editor / like Figma or Canva
- nhn/tui.image-editor
- ⚠️ 不维护
- 注意会收集统计 usageStatistics
- advanced-cropper/react-advanced-cropper
- evanw/glfx.js
- ⚠️ 不维护
- Demo https://evanw.github.io/glfx.js/demo/
- davidsonfellipe/lena.js
- filter
- DominicTobias/react-image-crop
- timeline
- gannt
- Block Editor/Page Builder
- 动画
- modal
- eBay/nice-modal-react
- react-responsive-modal
- link preview
- autocomplete
- input
- react-textarea-autosize
- table/Spreadsheet/Excel/Data Grid
- react-data-grid
- MIT, TS
- 41kB, 14kB
- react-spreadsheet
- MIT, TS
- 支持 formula
- @handsontable/formulajs, jstat, @reduxjs/toolkit, @reduxjs/toolkit, es-abstract, hot-formula-parser
- react-spreadsheet-grid
- MIT, JS
- 66kB, 17kB
- @silevis/reactgrid
- MIT, TS
- 250kB, 68kB
- react-datasheet
- ⚠️ 不再维护
- react-data-grid
- i18n - Unicode Language and Locale Identifiers
- react-i18next
- react-intl
- lingui
- rosetta
- next-intl
- formatjs
- hooks/utils
- for fun
- GEO/Map
- visgl/react-map-gl
- react for mapbox-gl, maplibre-gl
- maplibre/maplibre-gl-js
- BSD-3, Typescript
- mapbox-gl-js v1 fork
- mapbox/mapbox-gl-js
- 2020-12 修改为非开源协议
- v2 需要 token
- math
- Turfjs/turf
- MIT, TS
- geospatial engine
- Turfjs/turf
- tiles
- visgl/react-map-gl
- molefrog/spoiled
- tamagui/tamagui
- thebuilder/react-intersection-observer
- gabrielbull/react-desktop
- 模仿 macOS High Sierra 和 Windows 10 的组件
- reakit/reakit - 专注于 accessible 的组件
- ARIA
- 在国内一般不关心 accessible
- table-library/react-table-library
- 带 UI
- react-icons/react-icons
- react-icons.github.io 包含了大量可用 Icon
- 来自 tailwincss 的 heroicons 崇尚直接 copy svg 使用
- 简单方便
- @tabler/icons
- https://github.com/tabler/tabler-icons
- 4500, MIT
- https://github.com/tabler/tabler-icons
- popperjs/react-popper
- 显示弹出气泡
- signavio/react-mentions
- 支持
@username
- 支持
- twobin/react-lazyload
- 懒加载 UI 组件
- asabaylus/react-command-palette
- gilbarbara/react-joyride
- kanban
- notion
- https://github.com/bvaughn/planner
- ReactTooltip/react-tooltip
- floatingui
- reaviz
- https://github.com/wojtekmaj
- react-calendar, react-clock, react-pdf
编辑器
- Markdown
- margox/braft-editor
- margox/braft-extensions - 扩展包
路由
- ReactTraining/react-router
- React 16.8 hook 之前已经存在
- v6 基于 hook 重写,替代 reach-router
- v5 添加 hook 支持,Swith 和 Route 组件可选
- 支持 MemoryRouter,支持 React Native
- 核心组件
- Router - 提供 history 管理和上下文 - history 实现在 history 包
- BrowserRouter 基于当前 URL
- HashRouter 基于 URL 但使用
#/url
模式 - StaticRouter - 静态地址,用于 SSR
- NativeRouter - 支持 react-native
- 核心状态 location - 从 history 监听变化
- 提供 history 上下文 - useHistory
- 提供 Route 上下文 - useLocation、useParams
- Route - 匹配后渲染
- Switch - 只会渲染一个匹配的 Route
- Link, NavLink, Redirect - 导航,修改 url
- Prompt - 用于阻塞 history 发生变化
- Router - 提供 history 管理和上下文 - history 实现在 history 包
- useRoutes/react-router-config
- 提供了统一配置 route 的逻辑 - 很简单,可以作为参考
- matchRoutes - 匹配嵌套路由 - 返回匹配的 tree 路由数组
- renderRoutes - 渲染嵌套路由 - 递归 Switch, 遍历 Route
- @tanstack/react-router
- 参考/基于 React Router v6
- 内置 async import - 异步加载 element
- 内置 async load - 异步加载 data/状态 - useMatch 返回
- query 参数匹配、状态管理
- declarative API
- molefrog/wouter
- 轻量实现 - 很实用 - 可以直接拷贝到项目修改使用
- 可以不需要 context
- 外部提供 location
- minimalist-friendly ~2.1KB routing for React and Preact
reach/router- React Router v6 后 reach router 不再需要
- React Router 作者在 hook 出现后进行的尝试
- 目前 hook 能力已经合并回 react router v5
- 不使用 Swith 和 Route 组件,而是直接在组件上添加 path 进行匹配
- 参考
- The Future of React Router and @reach/router - 2019
- @reach/router 是在 hook 出现后的新尝试
- 现在所有 hook 功能也合并到了 react-router v5
- The Future of React Router and @reach/router - 2019
功能组件
大多为 Headless
- TanStack
- react-table
- 实现各种 table 功能
- react-query
- 异步查询缓存更新
- ranger
- range and multi-range sliders
- location
- virtual
- react-charts
- react-table
- vercel/swr
- 类似于 react-query 但更适合于前端定时刷新场景
- 支持 SSR
- gregberge/loadable-components
- 异步加载组件
- tailwindlabs/headlessui
- 功能性 headless 组件
- popover
- listbox/select
- combobox/autocomplete
- menu/dropdown
- switch/toggle
- disclosure
- dialog/modal
- radio group
- tabs
- transition
- nandorojo/dripsy
- its-danny/use-lilius
- date-fns
- DateInput
虚拟滚动
- petyosi/react-virtuoso
- 支持 list, table
- TanStack/virtual
- 基于 Hook
- 推荐 - 因为 react-virtualized 不活跃
- bvaughn/react-window - 虚拟滚动
- react-window vs react-virtualized
- Lodin/react-vtree
- 基于 react-window 实现的 tree 渲染
- bvaughn/react-virtualized
- 功能比 react-window 多但包更大
数据校验
- 一般都不是 react 相关
- 常用 yup, joi, props-type, json-schema
- json-schema
- 序列化好
- 工具支持
- 功能少 / 弱
- yup
- js 书写方便
- 但不方便序列化
- props-type
- React 组件属性校验
Form
- react-hook-form/react-hook-form
- 25kB/9kB
- 基于 hook 的 form 语意实现
- 轻量简单 - 没有复杂概念,直接 useForm 即可使用
- 状态独立 - 性能好
- 侵入性非常低
- 不强制要求 Form 上下文
- 可以通过 ref 注册
- 注意
- 默认 mode 为 submit - 在提交的时候才会校验
- 基于 ref 注册可能会被 deregister
- jaredpalmer/formik
- 基于组件构建表单
- 默认 Formik 全量渲染
- 组件 Field 封装
- 编码量较多
- formium
- 商业的 headless form builder
- final-form/react-final-form
- 基于 Final Form 的 React 封装
- 组件逻辑上类似 formik - 但要简单一点
- 核心 final form 也支持 vue、web component 等
- formnerd
- 商业的 form 提交服务
- data-driven-forms/form-builder
- 开源的 form builder
- 尚不成熟
- vazco/uniforms
- building forms from any schema
- Schemas
- JSON Schema
- GraphQL
- SimpleSchema
- Zod
- alibaba/formily
- 商业
unform/unform
样式
- class 合并
- gregberge/twc
- clsx
- classnames
- tailwind-merge
- cva
- tw-classed
- stitchesjs/stitches
- 写 Object 而不是写 string 的 css
- 类似 styled-components 和 emotion 的中间形态
- 相对性能更好,打包更小
- @stitches/react
- 支持 variant - 不只是单纯样式
- styled-components
- 包装现有组件,添加 className
- emotion-js/emotion
- 生成 className
- jsjoeio/styled-components-vs-emotion
- callstack/linaria
- 基于 babel 插件
- css-modules/css-modules
- vercel/styled-jsx
- styletron/styletron
- robinweser/fela State-Driven Styling
- cristianbote/goober
- linkedin/css-blocks
- 没有维护了
Hooks
- streamich/react-use
- 74kB/20kB
- alibaba/hooks
- riktar/uncino
状态管理
In React State vs Outside State
- Inside - 例如 useState, jotai, recoil
- 面向 React - 组件、上下文、Tree
- Outside - 例如 zustand, voltio/mobx
- 面向 数据/状态 - 函数、全局、跨组件
- 优势
- 框架无关
- 可在任意地方调用
- 劣势
- 可能有全局副作用
- SSR 不一定好处理 - #182
Proxy vs Selector
- 基于
代理
订阅 - 可以基于 路径 判断变化- 优势
- 使用更简单
- 不需要写 selector
- 不需要关心 compare
- 劣势
- 传递时要小心 - 比如读取对象,返回的是代理对象
- 尽量确保只有 基础数据类型 时使用
- 代理特殊对象要小心
- 例如: Map, Set, ReactElement, HTMLElement 之类的
- 需要考虑哪些能被代理,哪些不能
- 传递时要小心 - 比如读取对象,返回的是代理对象
- 区分 读 代理 和 写 代理
- selector 模式也可以用 写 代理
- 基于
代理
订阅主要指 读 代理 - 写 代理 修改操作可生成 operation - 可用于同步
- 优势
- 基于
selector
订阅 - 基于 值 判断变化- 优势
- 都是 原始 值 或 frozen 值
- 传递安全 - 不会有预期外结果,符合正常思路
- 劣势
- selector 写起来繁琐
- selector 可能还需要 useCallback 来 memo
- 需要考虑 compare 逻辑
- 每次添加用到数据 要嘛加 selector ,要嘛修改 现有 selector
- react-tracked 把基于 selector 变成基于 proxy
- 可以修改时使用 proxy 减少变化对比
- 例如 immer
- 优势
- 几种状态管理
- atom, in-react - jotai, recoil
- atom, outside-react - voltio
- state machine, in-react - redux
- state machine, outside-react - zustand
- https://github.com/pmndrs/valtio/issues/141#issuecomment-891214314
- pmndrs - 状态相关主要开发者也是 dai-shi
- dai-shi
- dai-shi/react-tracked
- 5kB/2kB - use-context-selector+proxy-compare
- 封装 useState, useStore
- 使用 proxy 订阅 - 操作上更方便
- 提供 memo 替代 React.memo - 因为要 比较/订阅 代理 对象
- dai-shi/use-context-selector
- 2kB/1kB
- useContext 支持 selector - 减少 rerender
- dai-shi/react-hooks-global-state
- global state for React with Hooks API without Context API
- dai-shi/react-hooks-worker
- custom hooks for web workers
- dai-shi/react-tracked
- effector
- Application stores should be as light as possible
- Application stores should be freely combined
- Autonomy from controversial concepts
- Predictability and clarity of API
- The application is built from simple elements
- mobxjs/mobx
- mobx 58kB/16kB
- mobx-react-lite 6kB/2kB
- 不支持 concurrent - mobx#2526
- 最近开发不活跃 - 功能已经足够完善
- use-sync-external-store
- use-subscription
- 更好的支持 concurrent 模式
- rematch/rematch
- teafuljs/teaful
- 基于 proxy 进行 select
- facebookexperimental/Recoil
- paol-imi/react-reparenting
- 实现切换 parent 不丢失状态
- jamiebuilds/unstated-next
- 简单封装 context+state - 共享业务状态逻辑,在状态基础上添加操作
- 反转 useHook
- FormidableLabs/react-fast-compare
- 用于在实现状态管理时快速比较是否发生变化
- 减少变化,避免刷新
- sandiiarov/use-deep-compare
- useDeepCompare{Callback,Effect,Memo,Memoize}
- 基于 dequal
- immerjs/use-immer
- useImmer - 基于 immer 的状态更新
- 当状态较多时能很大程度简化操作 - 从
setState(s=>({...s,loading:true}))
变为update(s=>{s.loading=true})
- tinyplex/tinybase
- Table, Row, Cell
- 订阅
- reactivex/rxjs
- rxjs 能非常简单的实现基于订阅的状态管理
- reduxjs/redux-toolkit
- redux-toolkit 简化了使用 redux 的难度
- 定义了使用规范
- storeon/storeon - 185 bytes event-based Redux-like state manager
- 事件驱动 - 内建
@init
,@dispatch
,@changed
- 初始化,分发,变化检测 const { dispatch, users, projects } = useStoreon('users', 'projects')
- 本质上是监听 @changed 来触发状态变化进行渲染
- storeon - index.js
- React hook - react/index.js
- 结构逻辑比 redux 清晰的多
- 事件驱动 - 内建
- reactivex/rxjs
- 常见问题
- 参考
图表
- react-d3-tree
- recharts/recharts
- 基于 d3 封装
- 功能比较原始 - 自定义能力较强 - 自定义 svg - 随意画图
- 类似于通过 react 渲染 svg - 但需要熟悉 svg 语法
- children 可以直接写 svg
- airbnb/visx
- React 渲染 SVG
- 预设了较多样式和图表元素
- FormidableLabs/victory
- plouc/nivo
- uber/react-vis
- 不太活跃
- plotly/react-plotly.js
- React 封装 plotly.js
- plotly.js - 所有图表都可以通过序列化的 JSON 表示
- 支持非常多的预设图表
- 显示支持一定程度自定义
- alibaba/BizCharts
- 阿里 BizCharts - 基于 G2 封装 React
- 封装程度高 - 支持较多类型图表
- G2Plot
- 基于 G2 封装的默认可用图表
- @ant-design/charts
- 基于 G2Plot 封装 React
- sbstjn/timesheet.js
- projectstorm/react-diagrams
- 节点流程图
- antvis/G2
- chartjs/Chart.js
- 基于 canvas
开发工具/生态
- storybookjs/storybook
将 UI 开发从主应用分离
- 不清楚如何选择,那就选择 Storybook
- 非常重
- 可能和项目内其他组件冲突 - React 17, PostCSS
- 支持多框架和平台 - React, Vue, WebComponent, React Native, Ember, Svelte, Preact, Marionette.js, Mithril, Marko, Riot, Rax, Flutter
- styleguidist/react-styleguidist
- 类似于 storybook,提供独立环境
- 实时编辑器
- doczjs/docz
- 组件 Doc 和 开发
- 基于 MDX
- 开发不活跃
- react-cosmos/react-cosmos Sandbox for developing and testing UI components in isolation
- Preact
- aidenybai/million
工具
- alexreardon/memoize-one
- 在组件外 memoize
- epoberezkin/fast-deep-equal
- FormidableLabs/react-fast-compare
- fork 自 fast-deep-equal
- 添加 react 类型处理,避免循环依赖
- welldone-software/why-did-you-render
动画
- pmndrs/react-spring
- framer/motion
- nandorojo/moti
- React Native (+ Web)
- by Reanimated 2
- React-Spring vs Framer Motion: Comparing Examples in Two Animation Libraries
- 实现动画底层逻辑不同
- framer-motion - duration-and-location
- 使用上会更舒徐
- react-spring - spring-physics
- 看起来会更真实
- framer-motion - duration-and-location
- 实现动画底层逻辑不同
- reactjs/react-transition-group
- 控制 css 类实现动画
- react-motion
- 不再维护 - 不推荐使用
- sghall/react-move
功能
- diegomura/react-pdf
- 使用 React 创建 PDF
- 支持 Node 和 Web
- SheetJS/sheetjs
- 不支持样式、图表、图片
- 性能好
- Pro https://sheetjs.com/pro
- exceljs/exceljs
参考
Rendering/Native
- scheduler
- DOM
- remarkablemark/html-react-parser
- ~28kB - gzip 10kB
- HTML to React
- 避免使用 WebComponent 方式
- 依赖
- 6k fb55/domhandler
- 10k react-property
- style-to-js
- style-to-object
- html-dom-parser
- inline-style-parser
- domelementtype
- 相关
- dompurify
- html-to-react
- remarkablemark/html-react-parser
- 3D/WebGL
- pmndrs/react-three-fiber
- Three.js 渲染引擎
- gre/gl-react
- WebGL 光栅
- pmndrs/react-three-fiber
- 2D/Canvas
- Native
- 小程序/跨端
- Terminal
- Yomguithereal/react-blessed
- blessed
- vadimdemedes/ink
- 终端 渲染引擎
- vadimdemedes/ink-ui
- vadimdemedes/pastel
- Next.js-like framework for CLIs made with Ink
- Yomguithereal/react-blessed
- Documents
- diegomura/react-pdf
- 使用 react 创建 PDF
- 渲染 PDF
- wojtekmaj/react-pdf
- 显示 PDF - 使用 pdfjs 并非 React 渲染
- diegomura/react-pdf
- chentsulin/awesome-react-renderer
有趣
- https://stackblitz.com/edit/demo-react-portal-ksmarb
- createPortal 就可以跨窗口
- https://github.com/ryanseddon/react-frame-component/blob/master/src/Frame.jsx#L133
- createPortal 可以在 IFrame 里渲染
- remotion-dev/remotion
- 非 OSS 协议
- Create videos programmatically in React
- lahmatiy/react-render-tracker
- refinedev/refine
- Build your React-based CRUD applications, without constraints.
- Aristona/react-phaser-three-game