Recoil — официальный менеджер состояния React для Facebook

React.js

Когда дело доходит до государственных менеджеров, колеса летят. В эпоху Class редукс и мобкс занимали почти весь рынок, и почти не было одноклассников, которые ни разу не пользовались редуксом. С рождением Hooks появилась новая партия колес, представители которых не указаны - следующий, состояние и так далее.
Конечно, независимо от того, какое колесо, проблема, которую нужно решить, одна и та же: ** Совместное использование состояния между компонентами. ** При решении этой основной задачи необходимо максимально соответствовать следующим характеристикам:

  • Поддержка TypeScript
  • Дружественная асинхронная поддержка
  • Поддерживать взаимозависимость государств
  • Поддерживает компоненты Class и Hooks
  • Простой в использовании

Опыт отдачи

Недавно Facebook официально выпустил решение для управления состоянием.Recoil, давайте испытать это.

Готов к работе

Чтобы использовать Recoil, нам нужно обернуть его в самый внешний слой проекта.RecoilRoot, что соответствует большинству менеджеров состояний, передающих данные между компонентами через контекст.

import React from 'react';
import { RecoilRoot } from 'recoil';

function App() {
  return (
    <RecoilRoot>
        ...
    </RecoilRoot>
  );
}

Совместное использование состояний между компонентами

Состояние проще всего определить и использовать. В отдаче, черезatomдля определения состояния.

const inputValueState = atom({
  key: "inputValue",
  default: ""
});

Как показано в приведенном выше коде, мы определяемinputValueСтатус, значением по умолчанию которого является пустая строка.
должен быть в курсеkeyполе, которое должно быть глобально уникальным. этоkeyВ основном для удобства отладки, постоянных данных (уникальный идентификатор при восстановлении данных) и удобного просмотра глобального дерева атомов.

Состояние потребления также относительно просто, черезuseRecoilStateдо состояния потребления.

import React from "react";
import { useRecoilState } from "recoil";
import { inputValue } from "../store";

const InputA = () => {
  const [value, setValue] = useRecoilState(inputValueState);

  return <input value={value} onChange={e => setValue(e.target.value)} />;
};

export default InputA;

Разве это не просто? Основное использование Recoil таково. Я написал один здесьdemo, вы можете испытать это.

2020-05-17 13.09.49.gif

государственная взаимозависимость

Некоторые состояния должны зависеть от других состояний, а затем использоватьselectorдля определения этого состояния.
Например, нам нужно определить новое состояниеfilterdInputValue, который является фильтромinputValueЗначение после числа в .

const filterdInputValue = selector({
  key: "filterdInputValue",
  get: ({get}) => {
    // 通过 get 可以读取其它状态
    const inputValue = get(inputValueState);
    return inputValue.replace(/[0-9]/ig, "");
  },
});

selectorОтносительно просто добиться зависимостей состояния. вы можете найти это в этомdemoИспытайте это.

2020-05-17 13.29.55.gif

Асинхронная поддержка

Хорошая поддержка асинхронных запросов важна для менеджеров состояний. Отдача обеспечиваетuseRecoilValueLoadableдля обработки асинхронных запросов. Непосредственно на примере:

const currentUserNameQuery = selector({
  key: "CurrentUserName",
  get: async () => {
    const response = await queryUserInfo();
    return response.name;
  }
});

нам нужно пройтиselectorопределить асинхронное состояние, еслиgetФункция является промисом, что означает, что состояние асинхронно и его нужно использовать.useRecoilValueLoadableпотреблять государство.

const UserName = () => {
  const userNameLoadable = useRecoilValueLoadable(currentUserNameQuery);
  switch (userNameLoadable.state) {
    case "hasValue":
      return <div>{userNameLoadable.contents}</div>;
    case "loading":
      return <div>Loading...</div>;
    case "hasError":
      throw userNameLoadable.contents;
  }
};

Как видно из приведенного выше примера,useRecoilValueLoadableВозвращенный статус может быть передан черезstateПоле считывает статус асинхронного запроса. я написалdemo, вы можете испытать это.

2020-05-17 15.34.53.gif


Конечно черезuseRecoilValueLoadableИспользование асинхронного состояния больше соответствует нашим нынешним привычкам. Но Recoil предпочитает проходитьReact.SuspenseИспользование асинхронного состояния здесь зависит от смотрящего, хотяSuspenseЭто может быть направление, но я не привык к нему.

const UserName = () => {
  const userName = useRecoilValue(currentUserNameQuery);
  return <>{userName}</>
 }
};
function MyApp() {
  return (
    <React.Suspense fallback={<div>Loading...</div>}>
      <UserName />
    </React.Suspense>
  );
}

оценивать

преимущество

  • Прежде чем государственный менеджер летал по всему небу, если чиновник может господствовать над миром, это должно быть хорошо.
  • Хорошая поддержка параллельного режима React.

недостаточный

Текущий Recoil все еще находится в стадии разработки, и документация не очень полная. Исходя из сложившейся ситуации, хотелось бы сказать несколько моментов о своих ощущениях.

1. Не реализовано с помощью ts, на данный момент не поддерживает ts

Меня это удивило, и только когда я написал эту статью, я обнаружил это, что очень странно. Разумно, для Recoil должно быть легко поддерживать машинописный текст, и, возможно, потребуется прийти позже.@types/recoil Бар.

2. В настоящее время нет поддержки состояния потребления компонентов класса.

Эта функция должна быть обязательной, и она не должна полностью отказываться от компонента класса. Предполагается, что эта функция обязательно будет поддерживаться в следующей версии. Стоимость реализации невысока, а если она не поддерживается, то слишком антигуманна.

3. Существует слишком много API, а начало работы требует определенных затрат.

image.png

Всего существует 19 API различных типов, которые довольно сложны. Я чувствую, что многие из них могут быть объединены, например,atom а такжеselectorСлиться в один и так далее (может быть, я незрелый). Предполагается, что чиновник может рассмотреть оптимизировать. Это было первоначально очень простым, но это было слишком сложно.

4. Потребление сложнее

Когда нам нужно использовать состояние, нам нужно импортировать две вещи, что громоздко.

import { useRecoilState } from "recoil";
import { inputValueState } from "../store";

// 用法
useRecoilState(inputValueState);

Должна была быть возможность передать строку напрямуюkeyПотребляется, но это та же проблема, что и редукс, который не может поддерживать ts.

import { useRecoilState } from "recoil";

useRecoilState('inputValueState');

В любом случае, импортировать две вещи нецелесообразно.

5. Недостаточно ярких моментов

Не видя ничего бросающегося в глаза, не пользуясь побуждениями. подожди и увидишь развитие~

постскриптум

Глядя на общую отдачу, можно сказать, что она относительно умеренная, и ее нужно развивать тихо.
Также порекомендуйте самый простой менеджер состояний React, который я сейчас использую.hox, есть только один API, он очень интуитивно понятен, не требует дополнительных затрат и полностью поддерживает хуки 😋.

Спасибо за прочтение

Обратите внимание на официальный аккаунт «Front-end Technology Bricks», тяните вас в группу обмена, и пусть все общаются и развиваются вместе.