What is the Recoil

Chinese website: www.recoiljs.cn/ Recoiljs.org/

The Recoil version of this article is 0.4.1

React state management is a React state management library

features

  1. Minimalist React style design

Recoil works in the same way and with the same principles as React. Add it to your application for fast, flexible state sharing.
Currently, only function components are supported h o o k s write \color{red}{currently only support function components, use hooks}

  1. Data flow diagram

Pure functions and efficient subscriptions are used for Derived data and asynchronous queries.
The written form is all pure functions, you can’t see the similarity a c t i o n , r e d u c e r , c o n n e c t Isotemplate code Var var var var var var var var var var var var var var var var var var var var var var

  1. Application global listening

Enables persistent storage, routing, time travel debugging, or undo by listening for all state changes in the application without affecting code splitting.
To be added \color{red}{to be added}

The motivation

For compatibility and simplicity, using React’s built-in state management capabilities is a better choice than using external global states. React has some limitations:

  • Sharing state between components can only be done by promoting state to their common ancestor, but doing so can result in rerendering a huge tree of components.
  • Context can only store a single value, not multiple sets of values with their own consumers.
  • Either way, it is difficult to separate code from the top layer of the component tree (where state must exist) from the leaf component (where state is used).

We wanted to improve the above issues while preserving the API and semantics, while keeping the React performance as close as possible.

Recoil defines an Directed graph that is orthogonal and naturally connected to your React tree. The change in state starts at the vertex of the graph (we call it atom) and flows through the pure function (we call it selector) to the component. Based on this implementation:

  • We can define apis that do not require template code, and the shared state has a get/set interface as simple as the React local state (although we can also encapsulate it using reducer, etc., if necessary).
  • We now have the possibility of compatibility with Concurrent mode and other React new features.
  • The definition of state is progressive and distributed, which makes code fragmentation possible.
  • Their local state can be replaced with derived data without modifying the corresponding components.
  • Derived data can be switched between synchronous and asynchronous without modifying the corresponding component.
  • Navigation can be treated as a first-class concept, and transitions of state can even be coded into links.
  • You can easily persist the state of the entire application in a traceable manner, and the persistent state is not lost as the application changes.

How to use (installation skipped)

  1. Reference RecoilRoot and wrap it around the root component, like React.Context
import React from 'react';
import { RecoilRoot } from 'recoil';

function App() {
    return (
        <RecoilRoot>
            <Root />
        </RecoilRoot>
    );
}
Copy the code
  1. Common concepts and apis
  • Atom

An Atom represents a state. Atom can be read and written from any component. The component that reads the Atom value implicitly subscribs to the Atom, so any updates to the Atom will cause the component to be rerendered using the corresponding Atom

const textState = atom({
  key: 'textState'.// unique ID (with respect to other atoms/selectors)
  default: ' '.// default value (aka initial value)
});
Copy the code
  • Get Atom->useRecoilState, useRecoilValue, useSetRecoilState

function CharacterCounter() {
  return (
    <div>
      <TextInput />
      <CharacterCount />
    </div>
  );
}

function TextInput() {
  const [text, setText] = useRecoilState(textState);
  // const text = useRecoilValue(textState);
  // const setText = useSetRecoilState(textState);
  // useRecoilState can be split into useRecoilValue and useSetRecoilState
  const onChange = (event) = > {
    setText(event.target.value);
  };

  return (
    <div>
      <input type="text" value={text} onChange={onChange} />
      <br />
      Echo: {text}
    </div>
  );
}
Copy the code
  • Selector

Selector represents a derived state, which is a transition of states. You can think of derived state as passing state to a pure function that modifies a given state in some way

const charCountState = selector({
  key: 'charCountState'.// unique ID (with respect to other atoms/selectors)
  get: ({get}) = > {
    const text = get(textState);

    returntext.length; }});Copy the code
  • To obtain the Selector – > useRecoilValue

function CharacterCount() {
  const count = useRecoilValue(charCountState);

  return <>Character Count: {count}</>;
}
Copy the code
  • atomFamily (todo)

  • selectorFamily (todo)

  1. Asynchronous components

The interface to a selector is always the same, so the component that uses that selector doesn’t need to care if it’s implemented with synchronous Atom state, derived selector state, or asynchronous query!

However, since the React render function is synchronous, what will it render before the Promise resolves? Recoil is designed to work with React Suspense for pending data. Wrapping your components in Suspense boundaries will catch any descendants that are still pending and render a callback UI.

import { memo, Suspense } from 'react';
import { selector, useRecoilValue } from 'recoil';

function CurrentTime() {
  const currentTime = selector({
    key: 'currentTime'.get: async ({get}) => {
      return await new Promise((resolve, reject) = > {
        setTimeout(() = > {
          resolve(new Date().valueOf())
        }, 2500)})}});const value = useRecoilValue(currentTime);
  return <div>{value}</div>;
}

function App() {

  return (
    <div className="App">
      <Suspense fallback={<div>Loading...</div>} ><CurrentTime />
      </Suspense>
    </div>
  );
}

export default memo(App);
Copy the code

other

  1. There is a debate in the community about whether key should be managed by the user
  2. If key repeats, there will be a warning
recoil.js:565 Duplicate atom key "textState". This is a FATAL ERROR in production. But it is safe to ignore this warning if it occurred because of hot module replacement.
Copy the code
  1. Browser developer tools

Recoilize, currently there is a version incompatible problem, can be timely attention, or according to the official example, to make a simple log plug-in

Chrome.google.com/webstore/de…