37
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:

  1. "Configuring a Redux store is too complicated"
  2. "I have to add a lot of packages to let Redux do anything useful"
  3. "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.

  1. redux-thunk -used to handle asynchronous actions (used with redux);
  2. redux-persist -used to store data locally (offline support);
  3. 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 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:

  1. Transmission/protocol/back-end agnostic data acquisition (REST, GraphQL, promise, etc.);
  2. Automatic cache + re-retrieval (re-verify when expired, window re-focus, polling/real-time);
  3. Parallel + dependent query;
  4. Mutation + reaction query retake;
  5. Multi-layer cache + automatic garbage collection;
  6. Paging + query based on cursor;
  7. Load more + infinite scroll query/scroll recovery;
  8. Request cancellation
  9. React Suspense + Fetch-As-You-Render query prefetch;
  10. 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

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

Easy to get started in seconds

  • 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 is developed based on TypeScript and Scss. It is powerful and has its own color and typesetting specifications. It is recommended.

image.png

It is a modular component library, divided into multiple packages (can be installed separately):

  1. core + components, more than 300 icons.
  2. datetime -6 components about date and time.
  3. icons + icons, supports svg and fonts formats.
  4. select -drop down to select 6 related components.
  5. table -Highly interactive table component (personally feel that the performance is not good).
  6. timezone -handles time zone related components.
  7. popover -Powerful pop-up box component, based on Popper.js .
  8. tooltip -provided by popover .
  9. contextMenu2 -provided by popover .
# 安装
$ 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 of root/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:

  1. XMLHttpRequest from the browser;
  2. http request from node.js;
  3. Support Promise API;
  4. Intercept requests and responses;
  5. Conversion request and response data;
  6. Cancel request
  7. Automatically convert JSON data;
  8. 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.

image.png

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.

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;}
}

5rhe3-upq2w.gif

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).

An animation library based on spring physics can basically meet most of the UI-related animation needs.

A group of components, used to manage component state (including loading and unloading) over time, specifically designed for animation.

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 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

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:

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

Options

  • jshint -relatively old library.
  • tslint -TypeScript linter, not recommended now.

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 , the prettier 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 or prettier.config.cjs to export module.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 welcome screen

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:

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 .


破晓L
2.1k 声望3.6k 粉丝

智慧之子 总以智慧为是