An in-depth guide on how to choose the perfect npm package.
React is a JavaScript library used to build user interfaces. It is not only a front-end UI development framework, but also a complete front-end development ecosystem.
Although React does not contain all the solutions, we can find NPM packages for different scenarios from the prosperous ecosystem to solve the problems encountered in development.
Today, we will start from the following 16 latitudes to find the best solution.
1. Global State Management
In 99% of applications, sharing state between components is mandatory, and there are some good local and external solutions.
recommend
If you ask me a solution, I would say Redux , not because it is the best, but because it is the most practical. Many companies are already using it, which means you also have to use it at some point.
In the past, we used Redux, which usually refers to the combination of Redux + React Redux, but now there is a more simplified solution: Redux Toolkit + React Redux, which helps us avoid three common problems of Redux:
- "Configuring a Redux store is too complicated"
- "I have to add a lot of packages to let Redux do anything useful"
- "Redux requires too much boilerplate code"
The Redux Toolkit simplifies the process of writing Redux logic and setting up the store, allowing us to write shorter logic that is easier to read, while still following the same Redux behavior and data flow.
# 安装 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
Sample code:
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.actions
const 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}
If you still use the Redux + React Redux combination solution, the Redux community also provides a lot of middleware to simplify various scenarios.
- redux-thunk -used to handle asynchronous actions (used with redux);
- redux-persist -used to store data locally (offline support);
- reselect -for faster query storage;
$ npm install redux react-redux redux-thunk redux-persist reselect --save
Options
- context -built-in with React, suitable for simple use, not conducive to performance, especially if you have a lot of changing data.
- recoil -Designed to solve specific problems, it is still in experimental state, accurate update, next-generation state management solution.
- jotai -Simple API, no string key, TypeScript oriented, and
react-spring
belong to Poimandres. - mobx -Follow the observer pattern, suitable for reactive programming, recommended for small and medium-sized projects.
2. Server status management
If your application relies heavily on some external data source, then managing that data (caching, updates, etc.) is critical to performance.
recommend
- react-query -a request library
react hooks
React Query will help you get, synchronize, update, and cache your remote data. It provides two simple hooks to complete operations such as adding, deleting, modifying, and querying.
It handles the caching
and more things out of the box. It is simple, powerful and configurable.
# 安装
$ npm i react-query --save
# or
$ yarn add react-query
Overview of basic functions:
- Transmission/protocol/back-end agnostic data acquisition (REST, GraphQL, promise, etc.);
- Automatic cache + re-retrieval (re-verify when expired, window re-focus, polling/real-time);
- Parallel + dependent query;
- Mutation + reaction query retake;
- Multi-layer cache + automatic garbage collection;
- Paging + query based on cursor;
- Load more + infinite scroll query/scroll recovery;
- Request cancellation
- React Suspense + Fetch-As-You-Render query prefetch;
- Dedicated Devtools.
Simple example (global configuration):
// main.js
import 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.jsx
import 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
Options
There is also a library similar to React Query.
The name "SWR" comes from stale-while-revalidate
: an HTTP cache invalidation strategy promoted HTTP RFC 5861 This strategy first returns the data (expired) from the cache, sends a fetch request (re-validation), and finally gets the latest data.
The main benefit of this library is that it was built by Vercel, who created Next.js. Therefore, you can expect better performance when using Next.js.
# 安装
$ npm i swr --save
# or
$ yarn add swr
SWR covers all aspects of performance correctness and stability to help you build a better experience:
- Quick page navigation
- Interval polling
- Data dependence
- Revalidate when focusing
- Re-verify when the network is restored
- Local cache update (Optimistic UI)
- Smart error retry
- Pagination and scroll position recovery
- React Suspense
- ...
3. Scaffolding
Creating a React application from scratch is complicated, and setting up webpack, babel, etc. can be daunting.
recommend
- create-react-app -the official scaffolding tool.
It encapsulates webpack and babel together to form a new scripting tool react-scripts to manage the entire application.
# 创建 React 项目
$ npx create-react-app my-app
# or
$ npm init react-app my-app
# or
$ yarn create react-app my-app
- vite -Use native ESM files without packaging, the next generation front-end development and construction tool.
Vite makes full use of the "native capabilities of the operating system", shortens the link, eliminates complicated packaging steps, and avoids many performance problems during construction. Vite has a "cross-age" meaning.
At present, although the Vite ecosystem is not as prosperous as Webpack, as time goes by, Vite will surely replace 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 -A framework for building React applications.
16125c05a0b91f out of the box, providing server-side rendering, static site generation, serverless functions, and more.
It is a toolbox, the most important feature is out-of-the-box SEO support, providing you with everything you need to create high-performance web applications.
# 创建 next.js 程序
$ npx create-next-app my-next-app
# or
$ yarn create next-app my-next-app
Next.js is built around the pages (pages) . A page is a React component exported .js
, .jsx
, .ts
or .tsx
file under the pages
directory.
Pages are associated with routes based on their file names. For example, pages/about.js
is mapped to /about
. You can even add dynamic routing parameters to the file name.
Options
If you start using React to build some basic projects, then you have other options.
- gatsby -Build a static content-oriented website, not suitable for other projects.
4. UI component library
A set of universal and complete UI library can not only help us solve repeated application scenarios, but also save development costs. The library performance after being tempered by the community is also guaranteed.
recommend
- antd -Comprehensive documentation, mature design system, rich ecology, preferred by the Chinese.
Antd is a React UI component library based on the Ant Design design system, which is mainly used for the research and development of enterprise-level mid- and back-end products.
# 安装
$ yarn add antd
# or
$ npm i antd --save
# 基于 Umi 搭建项目
$ yarn create @umijs/umi-app
# or
$ npx @umijs/create-umi-app
- blueprint -a React-based Web UI toolkit.
Blueprint is developed based on TypeScript and Scss. It is powerful and has its own color and typesetting specifications. It is recommended.
It is a modular component library, divided into multiple packages (can be installed separately):
core
+ components, more than 300 icons.datetime
-6 components about date and time.icons
+ icons, supports svg and fonts formats.select
-drop down to select 6 related components.table
-Highly interactive table component (personally feel that the performance is not good).timezone
-handles time zone related components.popover
-Powerful pop-up box component, based on Popper.js .tooltip
-provided bypopover
.contextMenu2
-provided bypopover
.
# 安装
$ yarn add @blueprintjs/core
# 使用 datetime
$ yarn add @blueprintjs/datetime
Blueprint supports Chrome, Firefox, Safari, IE 11 and Microsoft Edge.
Blueprint strictly adheres to semver in its public API:
- JS API exported from
blueprint
module ofroot/main
- HTML structure of the component;
- Render the CSS style of the component;
Options
- Material UI -Google's Material Design style, relatively difficult to customize.
- Semantic UI -Semantic, code readable and understandable, close to bootstrap style.
- React Bootstrap -Bootstrap component built with React.
5. Form Processing
This is the case with 90% of web applications-processing form input is a big pain. But we have some good solutions.
recommend
React Hook Form is the latest and greatest library for processing forms (in my opinion), it is very efficient and flexible.
It has good support for some external design libraries, such as material-ui
and ant-design
.
# 安装
$ npm i react-hook-form --save
# or
$ yarn add react-hook-form
Example:
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>
)
}
Options
There are some good options in this area.
- formik -Formik provides proven solutions for input validation, formatting, masking, arrays and error handling.
- redux-form-Not recommended, it will really hurt performance.
6. HTTP call
In the modern world, almost all websites rely on some external data sources, so making HTTP calls is very simple.
recommend
Axios is the recommended way to make HTTP calls.
- axios -A Promise-based HTTP client for browsers and nodejs.
Axios has the following characteristics:
- XMLHttpRequest from the browser;
- http request from node.js;
- Support Promise API;
- Intercept requests and responses;
- Conversion request and response data;
- Cancel request
- Automatically convert JSON data;
- The client supports to prevent CSRF/XSRF .
# 安装
$ npm i axios --save
# or
$ yarn add axios
// axios
axios.get(url)
.then((response) => console.log(response))
.catch((error) => console.log(error))
Options
In the case of small projects, only a few simple API calls are required, and Fetch is a good solution.
// fetch
fetch(url)
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) => console.log(error))
7. Style
You will need styles, there is no doubt that there are multiple ways to style the application.
recommend
Many people may disagree with me, but I think Styled Components is the best choice for styling in React applications.
Styled Components is CSS in JS . Other implementations include: radium , react-jss etc.
It helps to create clean components with a clear separation of concerns. In addition, it can be easily managed and configured through props.
# 安装
$ npm i styled-components --save
# or
$ yarn add styled-components
Example:
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>
)
}
Options
But, as I said, there are other great options!
- Cascading Style Sheets (CSS) -W3C standard, it should be no problem for smaller projects.
- sass -CSS preprocessing, it provides good functions for managing CSS, and is used in medium-sized or even larger projects.
- styled- -a library with functions very similar
styled-compomnents
- radium -An implementation of CSS in JS.
- react-jss -An implementation of CSS in JS.
8. Documentation
Good documentation can save more than 100 hours in the future. Therefore, proactively adopt the document library in the early stages of the project.
recommend
The recommended way to create a document is react-styleguidist
.
React Styleguidist is based on react-docgen , which can help the react project quickly build a library of project documentation.
The principle is to use react-docgen to parse the source file (untranslated). react-docgen finds the exported React components and generates documentation based on PropTypes or Flow annotations.
React Styleguidist uses the Markdown document: each JavaScript code block is rendered as an interactive demo react-simple-code-editor Remark extract all these code blocks).
Webpack loaders generates a JavaScript module containing all user components, documentation, and examples, and passes it to the React application, which renders the style guide.
# 安装 (node >= 14.0.0)
npm install react-styleguidist --save-dev
yarn add react-styleguidist --dev
When using React Styleguidist, you need to create a styleguide.config.js
file in the project root directory. The basic configuration is as follows:
// styleguide.config.js
module.exports = {
title: 'React Style Guide Example',
defaultExample: true,
webpackConfig: {
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
...
],
},
},
}
If you are using a vite2 , you need to manually install babel related dependencies:
# babel 7
$ yarn add babel-loader @babel/core @babel/preset-env babel/preset-react --dev
Then add babel configuration .babelrl
:
// .babelrc
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}
By default, the React Styleguidist search component location uses the glob pattern : src/components/**/*.{js,jsx,ts,tsx}
, which means that only the components under this path will generate documents.
The picture above is the documentation interface of React Styleguidist (you need to provide the .md
documentation).
Options
There are some other options.
- js-docs -A general documentation tool for JavaScript.
- react-docz -Very easy to use documentation guide, worth a try.
9. Multi-language support
If you are building products on a global scale, then you may want to add multilingual support to your React application.
recommend
Supports the internationalization of React applications and uses i18next and i18n ecosystems.
Options
There are some other good options.
It also supports other frameworks such as VueJS and Angular.
10. Animation
Animation brings your application to life. There are some good options for using animation in React.
recommend
Pure CSS is the best way to make React application animations. It is simple and fast, and its performance is guaranteed.
- CSS Animations -W3C standard CSS animations.
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;}
}
Options
If you want something ready-made. So here are some suggestions for you.
- react-motion -one of the official recommended libraries, cross-platform, the author is FB Great God Cheng Lou.
The library incorporates some physics and also TransitionGroup
(pre-V2 version).
- react-spring -one of the official recommended libraries.
An animation library based on spring physics can basically meet most of the UI-related animation needs.
- react-transition-group -one of the official recommended libraries.
A group of components, used to manage component state (including loading and unloading) over time, specifically designed for animation.
- framer-motion -production-ready animation and gesture library.
11. Long list rendering
Rendering a long list can severely affect the performance of the application, in this case it may be a good idea to use the library.
recommend
If you have some kind of infinite scrolling application, then you should consider React Window .
- react-window -antd virtual list solution.
react-window
is a more lightweight react-virtualized
, the same author (member of the React core team).
# 安装
$ npm install react-window --save
# or
$ yarn add react-window
Options
- react-virtualized
- react-paginate -If you don’t need an infinite scrolling list, then you can paginate the data.
12. Code Quality Tools
Linters can find any errors in the code statically, it is a good idea to use some kind of linters.
recommend
The preferred solution is Eslint .
# 安装 ( Node.js (^10.12.0, or >=12.0.0) )
$ npm install eslint --save-dev
# or
$ yarn add eslint --dev
Use Eslint needs to be configured by eslint --init
can be automatically generated configuration file in the root directory of the project eslintrc.js
.
$ npx eslint --init
# or
$ yarn run eslint --init
The Eslint configuration file supports multiple formats, and the order of priority is as follows:
.eslintrc.js
.eslintrc.cjs
.eslintrc.yaml
.eslintrc.yml
.eslintrc.json
package.json
Options
13. Format
Having a consistent visual style is very important for any application, and the code formatter can do the job for you!
recommend
This is the best solution for you, you don't need anything else!
# 安装 prettier
$ npm install prettier --save-dev --save-exact
# or
$ yarn add prettier --dev --exact
When using Prettier, you need to provide a configuration file. prettier
follows cosmiconfig , so you can configure it through (in order of priority).
- In
package.json
, theprettier
field is provided. - It can be a
.prettierrc
file, written in JSON or YAML format. - It can also be
.prettierrc.json
,.prettierrc.yml
,.prettierrc.yaml
, or.prettierrc.json5
. - You can also use
.prettierrc.js
,.prettierrc.cjs
,prettier.config.js
orprettier.config.cjs
to exportmodule.exports
- A
.prettierrc.toml
file.
For example, by using the .prettierrc
file to configure:
{
"trailingComma": "es5",
"tabWidth": 4,
"semi": false,
"singleQuote": true
}
Afterwards, all files can be formatted through command line instructions.
$ npx prettier --write .
# or
$ yarn prettier --write .
Prettier can also be integrated with the editor, see .
14. Analysis
Data analysis is the future. Most businesses today are data-driven. Therefore, it is very important to have a good analysis tool for your application!
recommend
The most popular and powerful tool is React Ga .
I don’t think you need anything else.
# 安装
$ npm install react-ga --save
After using the ReactGA.initialize
initialization parameters (id generated by Google Analytics), the React project will automatically include the script in the header.
15. Testing
I don't need to reiterate the importance of testing for any application. So please look down!
recommend
Recommended is the React Testing Library (also the official recommended testing library), which is an alternative to Enzyme
React Testing Library is completely different from Jest. It is one of the libraries that can test React components (and Enzyme, etc.).
It is very easy to use and is designed to follow usage in a real environment.
React Testing Library does not directly test the implementation details of components, but from the perspective of a React application. more in line with our original demands and best practices for unit testing.
It makes your test library maintainable in the long run, and makes refactoring a breeze. Refactoring of components (changes in implementation but not functionality) will not break your tests.
# 安装
$ npm install --save-dev @testing-library/react
# or
yarn add @testing-library/react --dev
Example:
// hidden-message.js
import * 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.js
import '@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 -the most popular JS testing framework.
Jest is a veteran test framework launched by Facebook and a test library installed by default by create-react-app
The responsibilities of Jest and React Testing Library are different. React Testing Library deals with react, and Jest deals with test cases.
Jest gives us the ability to run tests. In addition, Jest also provides a series of APIs, such as test suites, test cases, and assertions. Of course, Jest provides more than these, as well as spies, mocks, stubs, and so on.
If it is a React program created with CRA, you only need to install react-test-renderer
to present the snapshot. Snapshot testing is part of Jest. You can use the test renderer to quickly render the serializable HTML output of the virtual DOM instead of rendering the UI of the entire application.
$ yarn add react-test-renderer --dev
Options
Cypress is often compared to Selenium; however, Cypress is fundamentally and architecturally different. Cypress is not subject to the same restrictions as Selenium.
It can perform end-to-end testing, unit testing, integration testing, and can test anything that runs in the browser.
# 安装
$ npm install cypress --save-dev
# or
$ yarn add cypress --dev
16. Build shareable components
If you are in a large team, easily sharing components can become a big problem.
recommend
If you are looking for the most complete solution, Storybook is your best choice.
Storybook is a rapid development environment for UI components. It allows you to browse the component library, view the different status of each component, and interactively develop and test components. StoryBook helps you develop components independently of the application, which also helps improve the reusability and testability of components.
# 安装 storybook
$ npx sb init
Storybook needs to be installed in a project that has a framework set up, it is not suitable for empty projects. There are many ways to boot applications in a given framework, including:
- 📦 Create an Angular Workspace
- 📦 Create React App
- 📦 Vue CLI
- 📦 Ember CLI
- Other build tools (such as: Vite, etc.).
Finally, I think you now have a good understanding of when to choose which library. If you have any different ideas, please leave a message and let me know.
This article is inspired by 45-npm-packages-to-solve-16-react-problems .
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。