Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recoil 中默认值的正确处理 #268

Open
wayou opened this issue Mar 5, 2021 · 0 comments
Open

Recoil 中默认值的正确处理 #268

wayou opened this issue Mar 5, 2021 · 0 comments

Comments

@wayou
Copy link
Owner

wayou commented Mar 5, 2021

Recoil 中默认值的正确处理

继续使用 Recoil 默认值及数据级联的使用 的地域可用区级联的例子。

地域变更后可用区随之联动,两个下拉框皆默认选中第一个可选项。

从 URL 获取默认值

考虑这种情况,当 URL 中带了 query 参数指定地域时,想要默认选中指定的地域。

首先安装一个解析 query 的库 query-string 方便获取 query 并解析参数。

$ yarn add query-string

这样在地域组件中,就需要处理 URL 中的参数,如果发现带参,则更新地域信息。

RegionSelect.tsx

import { parse } from "query-string";
import React, { useEffect } from "react";
import { useRecoilState, useRecoilValue } from "recoil";
import { regionsState, regionState } from "./appState";

export function RegionSelect() {
  const regions = useRecoilValue(regionsState);
  const [region, setRegion] = useRecoilState(regionState);
  const regionId = parse(window.location.search).region;

  useEffect(() => {
    if (regionId) {
      const urlRegion = regions.find((region) => region.id === regionId);
      if (urlRegion) {
        setRegion(urlRegion);
      }
    }
  }, [regionId, regions, setRegion]);

  return (

  );
}

同时将当前地域信息打印出来,可以预见,上面因为在 useEffect 中处理的 URL 参数(组件中也只能在这里面处理),必然会有滞后性。也就是说,会先打印 beijing,再打印 URL 中指定的 shanghai

Screen Recording 2021-03-05 at 8 34 49 PM mov

useEffect 中处理URL 具有滞后性

在 Recoil 中处理

值得注意的是,atom 的默认值可以来自任何地方,异步数据或其他 atom 等,那当然也可以来自 URL。

按照这个思路将从 URL 获取地域的逻辑挪到 atom 的默认值获取逻辑中便解决了上述滞后的问题。

appState.ts

export const regionState = atom({
  key: "regionState",
  default: selector({
    key: "regionState/Default",
    get: ({ get }) => {
      const regions = get(regionsState);
+      const regionId = parse(window.location.search).region;
+      if (regionId) {
+        const urlRegion = regions.find((region) => region.id === regionId);
+        if (urlRegion) {
+          return urlRegion;
+        }
+      }
      return regions[0];
    },
  }),
});

Screen Recording 2021-03-05 at 8 44 25 PM mov

在 atom 中处理参数的获取

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant