Когда дело доходит до государственных менеджеров, колеса летят. В эпоху 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, вы можете испытать это.
государственная взаимозависимость
Некоторые состояния должны зависеть от других состояний, а затем использоватьselector
для определения этого состояния.
Например, нам нужно определить новое состояниеfilterdInputValue
, который является фильтромinputValue
Значение после числа в .
const filterdInputValue = selector({
key: "filterdInputValue",
get: ({get}) => {
// 通过 get 可以读取其它状态
const inputValue = get(inputValueState);
return inputValue.replace(/[0-9]/ig, "");
},
});
selector
Относительно просто добиться зависимостей состояния. вы можете найти это в этомdemoИспытайте это.
Асинхронная поддержка
Хорошая поддержка асинхронных запросов важна для менеджеров состояний. Отдача обеспечивает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, вы можете испытать это.
Конечно через
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, а начало работы требует определенных затрат.
Всего существует 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», тяните вас в группу обмена, и пусть все общаются и развиваются вместе.