对于如何抉择完满的 npm 包的深刻指南。

React 是用于构建用户界面的 JavaScript 库,它不仅是一个前端 UI 开发框架,更是一套残缺的前端开发生态体系。

尽管 React 没有蕴含所有的解决方案,然而咱们能够从凋敝的生态系统中找到应答不同场景的 NPM 包,来解决开发中遇到的问题。

明天,咱们就从以下 16 个纬度着手,寻找最佳解决方案。

1. 全局状态治理

在 99% 的应用程序中,组件之间共享状态是强制性的,并且有一些很好的本地和内部解决方案。

举荐

如果你问我一种解决方案,我会说 Redux,不是因为他是最好的,而是因为它是最实用的。许多公司曾经在应用它,意味着您也不得不在某个时刻应用它。

  • redux-toolkit + react-redux

以前咱们应用 Redux,通常是指 Redux + React Redux 组合计划,然而当初有了更简化的计划:Redux Toolkit + React Redux,它帮忙咱们防止了 Redux 的三个常见问题:

  1. "配置一个 Redux 存储太简单了"
  2. "我必须增加很多包能力让 Redux 做任何有用的事件"
  3. "Redux 须要太多样板代码"

Redux Toolkit 简化了编写 Redux 逻辑和设置 store 的过程,容许咱们编写更容易浏览的更短的逻辑,同时依然遵循雷同的 Redux 行为和数据流。

# 装置 react-toolkit(形式一)$ npm install @reduxjs/toolkit --save# or $ yarn add @reduxjs/toolkit# 还能够通过脚手架的 redux 模版装置应用(形式二)# Redux + Plain JS template$ npx create-react-app my-app --template redux# Redux + TypeScript template$ npx create-react-app my-app --template redux-typescript

示例代码:

import { createSlice, configureStore } from '@reduxjs/toolkit'const counterSlice = createSlice({  name: 'counter',  initialState: {    value: 0  },  reducers: {    incremented: state => {      state.value += 1    },    decremented: state => {      state.value -= 1    }  }})export const { incremented, decremented } = counterSlice.actionsconst store = configureStore({  reducer: counterSlice.reducer})store.subscribe(() => console.log(store.getState()))store.dispatch(incremented())// {value: 1}store.dispatch(incremented())// {value: 2}store.dispatch(decremented())// {value: 1}

如果您还是应用 Redux + React Redux 组合计划,Redux 社区也还提供了很多中间件来简化各种场景。

  1. redux-thunk - 用于解决异步动作(与 redux 应用);
  2. redux-persist - 用于本地存储数据(离线反对);
  3. reselect - 用于更快的查问存储;
$ npm install redux react-redux redux-thunk redux-persist reselect --save

备选计划

  • context - 内置与 React,适宜简略应用,不利于性能,特地是如果您有大量变动的数据。
  • recoil - 旨在解决特定问题,当初还是试验状态,精准更新、下一代状态治理计划。
  • jotai - 简洁的 API、没有字符串键、面向 TypeScript,与 react-spring 同属于 Poimandres 。
  • mobx - 遵循观察者模式,适宜响应式编程(reactive programming),举荐中小型我的项目应用。

2. 服务器状态治理

如果您的应用程序重大依赖某些内部数据源,那么治理该数据(缓存、更新等)对于性能至关重要。

举荐

  • react-query - 实用于 react hooks 的申请库。

React Query 将帮忙你获取、同步、更新和缓存你的近程数据, 提供两个简略的 hooks,就能实现增删改查等操作。

它解决 caching 古老的数据,以及更多开箱即用的货色,它简略、弱小且可配置。

# 装置$ npm i react-query --save# or$ yarn add react-query

基本功能概览:

  1. 传输/协定/后端不可知的数据获取(REST、GraphQL、promise等等);
  2. 主动缓存+从新取回(过期时从新验证,窗口从新聚焦,轮询/实时);
  3. 并行 + 依赖查问;
  4. 渐变 + 反应式查问重取;
  5. 多层缓存 + 主动垃圾收集;
  6. 分页 + 基于游标的查问;
  7. 加载更多 + 有限滚动查问/滚动复原;
  8. 申请勾销;
  9. React Suspense + Fetch-As-You-Render 查问预取;
  10. 专用的 Devtools。

简略示例(全局配置):

// main.jsimport React from 'react'import ReactDOM from 'react-dom'import App from './App'import { QueryClient, QueryClientProvider } from 'react-query'const queryClient = new QueryClient()ReactDOM.render(  <React.StrictMode>    <QueryClientProvider client={queryClient}>      <App />    </QueryClientProvider>  </React.StrictMode>  document.getElementById('root'))
// QueryExample.jsximport React from 'react'import { useQuery } from 'react-query'import { ReactQueryDevtools } from 'react-query/devtools'function QueryExample() {  const { isLoading, error, data, isFetching } = useQuery('repoData', () =>    fetch('https://api.github.com/repos/tannerlinsley/react-query').then((res) => res.json())  )  if (isLoading) return 'Loading...'  if (error) return 'An error has occurred: ' + error.message  return (    <div>      <h1>{data.name}</h1>      <p>{data.description}</p>      <strong> {data.subscribers_count}</strong> <strong>✨ {data.stargazers_count}</strong> <strong> {data.forks_count}</strong>      <div>{isFetching ? 'Updating...' : ''}</div>      <ReactQueryDevtools initialIsOpen />     </div>  )}export default QueryExample

备选计划

还有一个相似于 React Query 的库。

  • swr

“SWR” 这个名字来自于 stale-while-revalidate:一种由 HTTP RFC 5861 推广的 HTTP 缓存生效策略。这种策略首先从缓存中返回数据(过期的),同时发送 fetch 申请(从新验证),最初失去最新数据。

这个库的次要益处是它由 Vercel 构建的,他们是创立 Next.js 的人。因而,在应用 Next.js 时,您能够期待更好的性能。

# 装置$ npm i swr --save# or$ yarn add swr

SWR 涵盖了性能正确性和稳定性的各个方面,以帮你建设更好的体验:

  • 疾速页面导航
  • 距离轮询
  • 数据依赖
  • 聚焦时从新验证
  • 网络复原时从新验证
  • 本地缓存更新 (Optimistic UI)
  • 智能谬误重试
  • 分页和滚动地位复原
  • React Suspense
  • ...

3. 脚手架

从头开始创立 React 应用程序很简单,设置 webpack、babel 等会让人望而却步。

举荐

  • create-react-app - 官网脚手架工具。

它将 webpack 和 babel 封装在一起,组成一个新的脚本工具 react-scripts 来治理整个利用。

# 创立 React 我的项目$ npx create-react-app my-app# or$ npm init react-app my-app# or $ yarn create react-app my-app

  • vite - 应用原生 ESM 文件,无需打包,下一代前端开发与构建工具。

Vite 充分利用了「操作系统的原生能力」,缩短了链路,省去了繁冗的打包步骤,躲避了很多在在构建上时的性能问题,Vite具备「跨时代」的意义。

目前来看,尽管 Vite 生态没有 Webpack 凋敝,但随着工夫的推移, Vite 必将会代替 Webpack。

# 创立 react 我的项目# npm 6.x$ npm init vite@latest my-react-app --template react # npm 7+, 须要额定的双横线:$ npm init vite@latest my-react-app -- --template react# yarn$ yarn create vite my-react-app --template react
  • next.js - 构建 React 利用的框架。

Next.js 开箱即用,提供服务器端渲染、动态站点生成、无服务器性能等等。

它是一个工具箱,最重要的性能是开箱即用的 SEO 反对,为您提供创立高性能 web 应用程序所需的所有。

# 创立 next.js 程序$ npx create-next-app my-next-app# or$ yarn create next-app my-next-app

Next.js 是围绕着 页面(pages) 的概念结构的。一个页面(page)就是一个从 pages 目录下的 .js.jsx.ts.tsx 文件导出的 React 组件。

页面(page) 依据其文件名与路由关联。例如,pages/about.js 被映射到 /about。甚至能够在文件名中增加动静路由参数。

备选计划

如果您开始应用 React 构建一些根本我的项目,那么您还有其余抉择。

  • gatsby - 构建面向内容的动态网站,不适用于其余我的项目。

4. UI 组件库

一套通用欠缺的 UI 库不仅能帮忙咱们解决反复的利用场景,也能节俭开发成本,经社区锻炼后的库性能也有所保障。

举荐

  • antd - 文档全面,成熟的设计体系,生态丰盛,国人首选。

antd 是基于 Ant Design 设计体系的 React UI 组件库,次要用于研发企业级中后盾产品。

# 装置$ yarn add antd# or$ npm i antd --save# 基于 Umi 搭建我的项目$ yarn create @umijs/umi-app# or $ npx @umijs/create-umi-app
  • blueprint - 一个基于 React 的 Web UI 工具包。

Blueprint 基于 TypeScript 和 Scss 开发,功能强大,并且有本人的色调和排版标准,举荐应用。

它是一个模块化组件库,分为多个包(能够独自装置):

  1. core - 30+ 组件,300多个 icons。
  2. datetime - 对于日期和工夫的 6 个组件。
  3. icons - 300+ 图标,反对 svg 和 fonts 两种格局。
  4. select - 下拉抉择相干的 6 个组件。
  5. table - 高度交互的表格组件(个人感觉性能不咋地)。
  6. timezone - 解决时区相干的组件。
  7. popover- 弱小的弹出框组件,基于 Popper.js
  8. tooltip - 由 popover 提供。
  9. contextMenu2 - 由 popover 提供。
# 装置$ yarn add @blueprintjs/core # 应用 datetime$ yarn add @blueprintjs/datetime

Blueprint 反对 Chrome、Firefox、Safari、IE 11 和 Microsoft Edge。

Blueprint 在其公共 API 中严格遵守 semver:

  • blueprintroot/main 模块导出的 JS API;
  • 组件的 HTML 构造;
  • 渲染组件的 CSS 款式;

备选计划

  • Material UI - Google‘s Material Design 格调,定制绝对艰难。
  • Semantic UI - 语义化、代码可读性与可了解性很强,与 bootstrap 格调靠近。
  • React Bootstrap - 用 React 构建的 Bootstrap 组件。

5. 表单解决

90% 的 Web 应用程序都有这种情景 - 解决表单输出是一个很大的苦楚。但咱们有一些好的计划。

举荐

React Hook Form 是用于解决表单最新最好的库(集体认为),它十分高效且灵便。

  • react-hook-form

它对一些内部设计库有很好的反对,比方 material-uiant-design

# 装置$ npm i react-hook-form --save# or$ yarn add react-hook-form

示例:

import React from 'react'import { useForm } from 'react-hook-form'export default function HookForm() {  const {    register,    handleSubmit,    watch,    formState: { errors },  } = useForm()  const onSubmit = (data) => console.log(data)  // 通过 watch 能够监听 inupt 的变动  console.log(watch('username'))   return (    // handleSubmit 会在调用 onSubmit 之前验证用户输出    <form onSubmit={handleSubmit(onSubmit)}>      {/*通过 register 函数将输出注册到钩子中 */}      <input defaultValue="test" {...register('username')} />            {/* 通过 register 能够配置验证规定 */}      <input {...register('password', { required: true })} />            {/* 验证规定不通过时,将会显示如下内容  */}      {errors.exampleRequired && <span>This field is required</span>}      <input type="submit" />    </form>  )}

备选计划

这个畛域有一些很好的抉择。

  • formik - Formik 为输出验证、格式化、屏蔽、数组和错误处理提供了久经考验的解决方案。
  • redux-form - 不倡议应用 ,它真的会侵害性能。

6. HTTP 调用

在古代世界中,简直所有网站都依赖于一些内部数据源,所以进行 HTTP 调用非常简单。

举荐

Axios 是进行 HTTP 调用的举荐形式。

  • axios - 一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端。

Axios 具备如下特色:

  1. 从浏览器中创立 XMLHttpRequest;
  2. 从 node.js 收回 http 申请;
  3. 反对 Promise API;
  4. 拦挡申请和响应;
  5. 转换申请和响应数据;
  6. 勾销申请;
  7. 主动转换 JSON 数据;
  8. 客户端反对避免 CSRF/XSRF。
# 装置$ npm i axios --save# or $ yarn add axios
// axiosaxios.get(url)  .then((response) => console.log(response))  .catch((error) => console.log(error))

备选计划

  • Fetch - 浏览器原生 API,有别与 xhr。

小型我的项目的状况下,只须要几个简略的 API 调用,Fetch 是一个不错的解决方案。

// fetchfetch(url)  .then((response) => response.json())  .then((data) => console.log(data))  .catch((error) => console.log(error))

7. 款式

你将须要款式,这是毫无疑问的,有多种办法能够设置应用程序的款式。

举荐

许多人可能不批准我的认识,但我认为 Styled Components 是 React 应用程序中款式化的最佳抉择计划。

  • styled-components

Styled Components 是 CSS in JS 一种实现形式,其余实现形式还有:[radium]()、react-jss 等。

它有助于创立具备明确关注点拆散的洁净组件,此外,它能够通过 props 轻松治理和配置。

# 装置$ npm i styled-components --save# or$ yarn add styled-components 

示例:

import React from "react";import styled from "styled-components";const Container = styled.div`    padding: 12px;    background: red;    &:hover {        background: blue;}`const Homepage = () => {  return (      <Container>        <h1>Welcome to React<h1>    </Container>  )}

备选计划

然而,正如我所说,还有其余很棒的抉择!

  • Cascading Style Sheets (CSS) - W3C 规范,对于较小的我的项目应该没问题。
  • sass - CSS 预处理,它为治理 CSS 提供了很好的性能,应用于中型甚至更大的我的项目。
  • styled-jsx - 与 styled-compomnents 性能很类似的库。
  • radium - CSS in JS 的一种实现。
  • react-jss - CSS in JS 的一种实现。

8. 文档

好的文档能够在将来节俭 100 多个小时,因而,在我的项目的晚期就积极主动的采纳文档库。

举荐

举荐创立文档的形式是 react-styleguidist

  • react-styleguidist

React Styleguidist 基于 react-docgen ,能够帮忙 react 我的项目疾速构建我的项目文档的库。

其原理是应用 react-docgen 来解析源文件(未转译)。react-docgen 查找导出的 React 组件并依据 PropTypes 或 Flow 正文生成文档。

React Styleguidist 应用 Markdown 文档:每个 JavaScript 代码块都被渲染为带有 react-simple-code-editor 的交互式演示(应用 Remark 提取所有这些代码块)。

Webpack loaders 生成蕴含所有用户组件、文档和示例的 JavaScript 模块,并将其传递给 React 应用程序,该应用程序渲染款式指南。

# 装置 (node >= 14.0.0)npm install react-styleguidist --save-devyarn add react-styleguidist --dev

在应用 React Styleguidist 时,须要在我的项目根目录下建设 styleguide.config.js 文件,根本配置如下:

// styleguide.config.jsmodule.exports = {  title: 'React Style Guide Example',  defaultExample: true,  webpackConfig: {    module: {      rules: [        {          test: /\.jsx?$/,          exclude: /node_modules/,          loader: 'babel-loader',        },        ...      ],    },  },}

如果应用的是 vite2 构建的 React 我的项目,则须要手动装置 babel 相干依赖:

# babel 7$ yarn add babel-loader @babel/core @babel/preset-env babel/preset-react --dev

而后增加 babel 配置 .babelrl

// .babelrc{    "presets": [        "@babel/preset-env",        "@babel/preset-react"    ]}

默认状况下,React Styleguidist 搜寻组件的地位应用的是 glob模式:src/components/**/*.{js,jsx,ts,tsx},也就是说位于这个门路下的组件才会生成文档。

上图是 React Styleguidist 的文档界面(编写文档须要提供与组建同名的 .md 文件) 。

备选计划

还有一些其余抉择。

  • js-docs - JavaScript 的通用文档工具。
  • react-docz - 十分易于应用的文档指南,值得一试。

9. 多语言反对

如果您正在寰球范畴内构建产品,那么您可能心愿在 React 应用程序中增加多语言反对。

举荐

  • react-i18next

反对 React 应用程序国际化,应用 i18next、i18n 生态系统。

  • i18next

备选计划

还有其余一些不错的抉择。

  • react-intl

它也反对其余框架,如 VueJS 和 Angular。

10. 动画

动画使您的应用程序栩栩如生。在 React 中应用动画有一些不错的抉择。

举荐

纯 CSS 是制作 React 应用程序动画的最佳形式,它简略快捷,性能也有保障。

  • CSS Animations - W3C 规范的 CSS 动画。
const [name, setName] = useState('')...function App() {  return (    <div>        <div className={['example', name].join(' ')}></div>      <button onClick={() => setName('example-animation')}>点击</button>    </div>  )}
.example {  width: 100px;  height: 100px;  background-color: red;  animation-duration: 4s;}.example-animation {  animation-name: example;}@keyframes example {  0%   {background-color: red;}  25%  {background-color: yellow;}  50%  {background-color: blue;}  100% {background-color: green;}}

备选计划

如果您想要现成的货色。那么这里有一些倡议给您。

  • react-motion - 官网举荐库之一,跨平台, 作者是 FB 大神 Cheng Lou。

该库交融了一些物理学的货色,还为 React 的 TransitionGroup (V2 之前的版本)提供了一些更弱小的 API。

  • react-spring - 官网举荐库之一。

基于弹簧物理学的动画库,基本上能满足大多数与 UI 相干的动画需要。

  • react-transition-group - 官网举荐库之一。

一组组件,用于随工夫治理组件状态(包含装载和卸载),专门针对动画设计。

  • framer-motion - 生产就绪动画、手势库。

11. 长列表渲染

渲染一个长列表会重大影响应用程序的性能,在这种状况下应用库可能是一个好主见。

举荐

如果你有某种有限滚动的应用程序, 那么你应该思考 React Window

  • react-window - antd 虚构列表的解决方案。

react-window是是更轻量级的 react-virtualized, 同出一个作者(React 外围团队成员)。

# 装置$ npm install react-window --save# or$ yarn add react-window

备选计划

  • react-virtualized
  • react-paginate - 如果您不须要有限滚动列表,那么您能够对数据进行分页。

12. 代码品质工具

Linters 能够动态地发现代码中的任何谬误,应用某种 linter 是个好主见。

举荐

首选解决方案是 Eslint

  • eslint
# 装置 ( Node.js (^10.12.0, or >=12.0.0) )$ npm install eslint --save-dev# or$ yarn add eslint --dev

应用 Eslint 须要进行配置,通过 eslint --init 能够在我的项目根目录下主动生成配置文件 eslintrc.js

$ npx eslint --init# or $ yarn run eslint --init

Eslint 配置文件反对多种格局,优先级程序如下:

  1. .eslintrc.js
  2. .eslintrc.cjs
  3. .eslintrc.yaml
  4. .eslintrc.yml
  5. .eslintrc.json
  6. package.json

备选计划

  • jshint - 比拟旧的库。
  • tslint - TypeScript 的 linter,当初不举荐。

13. 格式化

具备统一的视觉款式对于任何应用程序都十分重要,代码格式化程序能够为您实现这项工作!

举荐

  • prettier

这对您来说是最好的解决方案,您不须要其余任何货色!

# 装置 prettier$ npm install prettier --save-dev --save-exact # or $ yarn add prettier --dev --exact

应用 Prettier 时须要提供配置文件,prettier 遵循 cosmiconfig ,所以您能够通过(按优先程序)进行配置配置。

  • package.json 中,提供 prettier 字段。
  • 能够是一个 .prettierrc文件,应用 JSON 或 YAML 格局编写。
  • 也能够是.prettierrc.json.prettierrc.yml.prettierrc.yaml,或.prettierrc.json5文件。
  • 还能够应用 .prettierrc.js.prettierrc.cjsprettier.config.jsprettier.config.cjs 通过 module.exports 导出。
  • 一个.prettierrc.toml文件。

例如通过应用 .prettierrc 文件进行配置:

{  "trailingComma": "es5",  "tabWidth": 4,  "semi": false,  "singleQuote": true}

之后能够通过命令行指令对所有文件进行格式化操作。

$ npx prettier --write .# or $ yarn prettier --write .

Prettier 还能够与编辑器进行集成,详见 。

14. 剖析

数据分析就是将来,明天的大多数企业都是数据驱动的,因而,为您的应用程序领有一个好的剖析工具十分重要!

举荐

最风行和最弱小的工具是 React Ga

  • react-ga

我认为您不须要其余任何货色。

# 装置$ npm install react-ga --save

当应用 ReactGA.initialize 初始化参数(谷歌剖析生成的 id)后,React 我的项目会主动在 header 中引入 Google Analytics 脚本。

15. 测试

我不须要重申测试对于任何应用程序的重要性。所以请往下看!

举荐

举荐的是 React Testing Library(也是官网举荐的测试库),是 Airbnb 的 Enzyme 测试库的代替计划。

React Testing Library 和 Jest 是截然不同的,它是其中一个能够测试 React 组件的库(还有 Enzyme 等)。

  • react-testing-library
它十分易于应用,并且旨在遵循实在环境中的应用状况。

React Testing Library 不间接测试组件的实现细节,而是从一个 React 利用的角度去测试。 更加合乎咱们对于单元测试的本来诉求,以及最佳实际。

它让您的测试库从久远来看是可保护的,让重构工作变得轻而易举,组件的重构(更改实现但不是性能)不会毁坏您的测试。

# 装置$ npm install --save-dev @testing-library/react# oryarn add @testing-library/react --dev

示例:

// hidden-message.jsimport * as React from 'react'// NOTE: React Testing Library works well with React Hooks and classes.// Your tests will be the same regardless of how you write your components.function HiddenMessage({children}) {  const [showMessage, setShowMessage] = React.useState(false)  return (    <div>      <label htmlFor="toggle">Show Message</label>      <input        id="toggle"        type="checkbox"        onChange={e => setShowMessage(e.target.checked)}        checked={showMessage}      />      {showMessage ? children : null}    </div>  )}export default HiddenMessage
// __tests__/hidden-message.jsimport '@testing-library/jest-dom' // jest-dom 更不便的为测试增加断言,倡议应用,但不是必须的import * as React from 'react'import {render, fireEvent, screen} from '@testing-library/react'import HiddenMessage from '../hidden-message'test('shows the children when the checkbox is checked', () => {  const testMessage = 'Test Message'  render(<HiddenMessage>{testMessage}</HiddenMessage>)  //query* 函数将返回元素,如果找不到,则返回 null  //get* 函数将返回元素,如果找不到,则抛出谬误           expect(screen.queryByText(testMessage)).toBeNull()  //查问能够承受正则表达式,使选择器对内容调整和更改更具弹性  fireEvent.click(screen.getByLabelText(/show/i))  // .toBeInTheDocument() 是一个来着jest-dom 的断言  // 还能够应用 .toBeDefined()  expect(screen.getByText(testMessage)).toBeInTheDocument()})
  • jest - 最受欢迎的 JS 测试框架。

Jest 是 Facebook 推出的老牌测试框架,也是 create-react-app 默认装置的测试库。

Jest 和 React Testing Library 的职责是不同的,React Testing Library 是跟 react 打交道,Jest 是跟测试用例打交道。

Jest 给予咱们运行测试的能力,除此之外,Jest 还提供了一系列 API,例如 test suites、test cases、assertions,当然 Jest 提供的还不止这些,还有 spies、mocks、stubs 等等。

如果是应用 CRA 创立的 React 程序,则只须要装置 react-test-renderer 来出现快照。 快照测试是 Jest 的一部分。 您能够应用测试渲染器疾速出现虚构 DOM 的可序列化 HTML 输入,而不是出现整个应用程序的UI。

$ yarn add react-test-renderer --dev

备选计划

  • cypress

Cypress 通常被比作 Selenium;然而,Cypress 在基本上和架构上都不同。Cypress 不受与 Selenium 雷同的限度。

它可能进行端到端测试、单元测试、集成测试,能够测试在浏览器中运行的任何货色。

# 装置$ npm install cypress --save-dev# or$ yarn add cypress --dev

16. 构建可共享的组件

如果您在一个大型团队中,那么轻松共享组件可能会成为一个大问题。

举荐

  • storybook

如果您正在寻找最残缺的解决方案,Storybook 是您的最佳抉择。

Storybook 是 UI 组件的疾速开发环境。它容许你浏览组件库,查看每个组件的不同状态,以及交互式开发和测试组件。StoryBook 可帮忙你独立于利用程序开发组件,这也有助于进步组件的可重用性和可测试性。

# 装置 storybook$ npx sb init

Storybook 须要装置到曾经设置了框架的我的项目中,它不适用于空我的项目。有很多办法能够在给定的框架中疏导应用程序,包含:

  • Create an Angular Workspace
  • Create React App
  • Vue CLI
  • Ember CLI
  • 其余构建工具(如:Vite 等)。

最初,我想当初您对何时抉择哪个库有了很好的理解,如果您有任何不同的想法,请留言通知我。

本文启发于 45-npm-packages-to-solve-16-react-problems。