Skip to main content

React Awesome

tip
  • 专门功能选择专业组件 - Headless 配合 UI 组件达到更为理想的结果
    • react-table
    • react-hook-form
    • react-popper
  • 选择样式与组件独立的 UI 库
    • bluprintjs
  • 避免选择绑定了功能的组件
    • 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 组件

  • palantir/blueprint
    • CSS 样式定义 + React 封装组件
    • 很多组件都可以直接 HTML + CSS 类定义达到效果 - 非常清晰明了
    • npm 包含源码 - IDE 能直接看到组件源码
    • @blueprintjs/select
      • 多功能 select 组件
      • 不控制样式,以逻辑为主
  • radix-ui/primitives
    • by WorkOS
  • nextui-org/nextui
  • rsuite/rsuite
    • 各方面神似 AntD - 但比 AntD 轻的多
  • ant-design/ant-design - 不建议产品使用
    • 丰富强大的组件库
    • 过于 高度封装
      • 做出来的东西都差不多,一眼能看出来是 AntD 组件
      • 难自定义
      • 想把什么都做掉做好 - 但结果并不理想
    • 大量依赖 外部组件
      • 43 个依赖 - npm dependencies
      • 大量 rc-xxx - 外部组件用于实现单一功能 - 功能非常复杂
      • 但单一功能却都又比不上 react-table、react-hook-form 之类的专门组件 - 食之无味,弃之可惜
      • 且导致版本变化可能组件直接不兼容 - 例如 3->4 Form 和 Table
      • 大多 rc-xxx 的类型定义缺失,对 TS 也不友好,难看得到有什么属性 - 需要的时候得翻 rc-xxx 源码,但质量堪忧
    • icon 组件现在不允许使用字符串,需要引入具体组件
      • 用开发便捷性换取 bundle size - 觉得不值得 - 因为 antd 一般用于后台系统,bundle size 次要
      • icon 难以直接配置使用
    • 版本变化样式各方面变化较大 - 即便是小版本变化
      • 导致基本不可能自定义 antd 内部组件样式 - 维护成本高
  • mui-org/material-ui - Material Design 风格
    • 如果选择 MD 风格则非常匹配
    • 完成程度和成熟度远远高于 antd
    • 组件非常多,支持高度样式自定义
  • geist-org/geist-ui
    • 类似 vercel 的设计风格
  • arco-design/arco-design
  • 公司相关设计风格组件库
  • 其他风格
  • supabase/ui
  • ebs-integrator/ebs-design

移动端 UI 组件

特殊 UI 组件

编辑器

路由

  • 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 发生变化
    • useRoutes/react-router-config
      • 提供了统一配置 route 的逻辑 - 很简单,可以作为参考
      • matchRoutes - 匹配嵌套路由 - 返回匹配的 tree 路由数组
      • renderRoutes - 渲染嵌套路由 - 递归 Switch, 遍历 Route
  • tannerlinsley/react-location
    • 参考/基于 React Router v6
    • 内置 async import - 异步加载 element
    • 内置 async load - 异步加载 data/状态 - useMatch 返回
    • query 参数匹配、状态管理
    • declarative API
  • molefrog/wouter
    • 轻量实现 - 很实用 - 可以直接拷贝到项目修改使用
    • 外部提供 location
  • reach/router
    • React Router v6 后 reach router 不再需要
    • React Router 作者在 hook 出现后进行的尝试
    • 目前 hook 能力已经合并回 react router v5
    • 不使用 Swith 和 Route 组件,而是直接在组件上添加 path 进行匹配
  • 参考

功能组件

大多为 Headless

虚拟滚动

数据校验

  • 一般都不是 react 相关
  • 常用 yup, joi, props-type, json-schema
  • json-schema
    • 序列化好
    • 工具支持
    • 功能少 / 弱
  • yup
    • js 书写方便
    • 但不方便序列化
  • props-type
    • React 组件属性校验

Form

样式

Hooks

状态管理

In React State vs Outside State
  • Inside - 例如 useState, jotai, recoil
    • 面向 React - 组件、上下文、Tree
  • Outside - 例如 zustand, voltio
    • 面向 数据/状态 - 函数、全局、跨组件
    • 优势
      • 框架无关
      • 可在任意地方调用
    • 劣势
      • 可能有全局副作用
      • 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

图表

开发工具

  • 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

工具

动画

功能

参考

Rendering/Native

有趣

Internal