日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747


深入Facebook 官方React 狀態管理器Recoil講解

 

作者: 磚家

轉發鏈接:https://mp.weixin.qq.com/s/cjwv25hSLBsUQ9m5De6vUg

前言

說到狀態管理器,輪子滿天飛。在 Class 時代,redux 與 mobox 幾乎占據了全部市場,幾乎沒有沒用過 redux 的同學。隨著 Hooks 的誕生,新的一批輪子應運而生,其中有代表性的有 unstated-next、constate 等等。當然無論什么輪子,要解決的問題都是一樣的:跨組件狀態共享。在解決這個核心問題的同時,需要盡可能的滿足以下幾個特性:

  • TypeScript 支持
  • 友好的異步支持
  • 支持狀態互相依賴
  • 同時支持 Class 與 Hooks 組件
  • 使用簡單

Recoil 體驗

最近,facebook 官方出了一個狀態管理器解決方案 Recoil[1],我們來體驗一下。

準備工作

使用 Recoil,我們需要在項目最外層包一個 RecoilRoot ,這個和大部分狀態管理器一致,通過 context 來跨組件傳遞數據。

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

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

 

跨組件狀態共享

狀態最簡單的就是定義和使用。在 Recoil 中,通過 atom 來定義一個狀態。

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

如上面的代碼所示,我們定義了一個 inputValue 狀態,它的默認值是空字符串。需要注意的是 key 字段,它應該是全局唯一的。這個 key 主要為了 debug 方便,持久化數據(數據恢復時的唯一標識),以及可以方便的看到全局 atoms 樹。消費狀態也比較簡單,通過 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[2],你可以體驗下。

狀態互相依賴

有些狀態需要依賴其它狀態,這時候就要用 selector 來定義這個狀態了。比如,我們需要定義一個新的狀態 filterdInputValue ,它是過濾 inputValue 中的數字后的值。

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

selector 比較簡單,就是為了實現狀態的依賴。你可以在這個 demo[3] 體驗下。

異步支持

良好的異步請求支持是狀態管理器必不可少的。Recoil 提供了一個 useRecoilValueLoadable 來處理異步請求。直接上例子:

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

我們需要通過 selector 來定義異步狀態,如果 get 函數是一個 Promise,則代表該狀態為異步狀態,需要使用 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[4],你可以體驗下。

深入Facebook 官方React 狀態管理器Recoil講解

 

當然通過 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 concurrent 模式支持良好。

不足

當前 Recoil 還處于開發階段,文檔都還不是很全。基于現狀,說幾點我的感受。

1. 沒有使用 ts 實現,目前不支持 ts

這點我很驚訝,也是寫這個文章的時候才發現的,很奇怪。講道理 Recoil 支持 typescript 應該是順手的事情,可能后期需要來個 @types/recoil 吧。

2. 目前沒有支持 Class 組件消費狀態。

這個特性應該是必備的,應該不會徹底拋棄 Class 組件。估計下個版本肯定會支持的這個特性的。實現成本較低,不支持的話就太反人類了。

3. API 偏多,有一定上手成本。

深入Facebook 官方React 狀態管理器Recoil講解

 

各類 API 一共有 19 個,偏復雜了。感覺很多都是可以合并的,比如 atom 和 selector 合并成一個等等(也可能是我考慮不成熟)。建議官方可以考慮精簡精簡,本來是一個很簡單的東西,搞的太復雜了。

4. 消費較繁瑣

我們需要消費一個狀態的時候,需要 import 兩個東西,比較繁瑣。

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

// 用法
useRecoilState(inputValueState);

本來應該可以直接通過字符串 key 消費的,但這樣和 redux 問題一樣了,無法支持 ts。

import { useRecoilState } from "recoil";

useRecoilState('inputValueState');

無論如果,import 兩個東西不是一個好的用法。

5. 沒有足夠的亮點

沒有看到讓人眼前一亮的東西,沒有使用沖動。靜觀發展~

后記

Recoil 整體看下來,比較中庸,需要靜觀發展。另外推薦一下我目前正在用的最簡單的 React 狀態管理器 hox[5],只有一個 API,非常符合直覺,沒有任何上手成本,完全擁抱 Hooks 。

分享到:
標簽:Facebook
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定