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

[React] Recoil 里面 selectorFamily 的作用是什么?和 selector 有啥区别【热度: 200】 #1095

Open
yanlele opened this issue Feb 10, 2025 · 0 comments
Labels
web框架 web 框架相关知识
Milestone

Comments

@yanlele
Copy link
Member

yanlele commented Feb 10, 2025

关键词:Recoil selector 和 selectorFamily

在 Recoil 中,selectorFamilyselector 都是用于创建派生状态的工具,但它们在使用场景和功能上存在一些差异,下面为你详细介绍它们的作用以及区别。

selector 的作用

selector 用于创建派生状态,它可以根据一个或多个原子(atom)状态计算出新的状态。selector 的值会自动进行记忆化,只有当依赖的状态发生变化时才会重新计算。以下是一个简单的 selector 示例:

import { atom, selector, useRecoilValue } from "recoil";

// 定义一个原子状态
const textState = atom({
  key: "textState",
  default: "Hello, Recoil!",
});

// 定义一个 selector,它依赖于 textState
const textLengthState = selector({
  key: "textLengthState",
  get: ({ get }) => {
    const text = get(textState);
    return text.length;
  },
});

const App = () => {
  const textLength = useRecoilValue(textLengthState);
  return (
    <div>
      <p>Text length: {textLength}</p>
    </div>
  );
};

在这个例子中,textLengthState 是一个 selector,它根据 textState 的值计算文本的长度。

selectorFamily 的作用

selectorFamilyselector 的一种扩展,它允许你创建一系列相关的 selector,这些 selector 可以根据传入的参数动态生成。这在需要根据不同的输入生成不同的派生状态时非常有用,比如根据不同的 ID 获取不同的数据。以下是一个 selectorFamily 的示例:

import { atom, selectorFamily, useRecoilValue } from "recoil";

// 模拟一个数据集合
const dataState = atom({
  key: "dataState",
  default: {
    1: { name: "Item 1" },
    2: { name: "Item 2" },
    3: { name: "Item 3" },
  },
});

// 定义一个 selectorFamily
const itemSelectorFamily = selectorFamily({
  key: "itemSelectorFamily",
  get:
    (itemId) =>
    ({ get }) => {
      const data = get(dataState);
      return data[itemId];
    },
});

const App = () => {
  const item1 = useRecoilValue(itemSelectorFamily(1));
  const item2 = useRecoilValue(itemSelectorFamily(2));

  return (
    <div>
      <p>Item 1: {item1?.name}</p>
      <p>Item 2: {item2?.name}</p>
    </div>
  );
};

在这个例子中,itemSelectorFamily 是一个 selectorFamily,它根据传入的 itemIddataState 中获取相应的数据。通过不同的 itemId 可以获取不同的派生状态。

两者的区别

  • 参数化能力
    • selector:没有参数化的能力,它的依赖和计算逻辑是固定的,每次使用时都会计算相同的派生状态。
    • selectorFamily:支持参数化,可以根据传入的不同参数生成不同的 selector 实例,从而计算出不同的派生状态。
  • 使用场景
    • selector:适用于派生状态的计算逻辑固定,不依赖外部参数的场景,比如根据一个固定的原子状态计算其长度、总和等。
    • selectorFamily:适用于需要根据不同的输入动态生成派生状态的场景,比如根据不同的 ID 获取不同的数据、根据不同的筛选条件获取过滤后的数据等。
  • 记忆化机制
    • selector:对整个 selector 进行记忆化,只要依赖的状态不变,就不会重新计算。
    • selectorFamily:对每个根据不同参数生成的 selector 实例进行记忆化,不同参数对应的实例之间相互独立,每个实例的计算结果会分别进行记忆化。

综上所述,selectorFamilyselector 的增强版本,当你需要根据不同的参数动态生成派生状态时,应该使用 selectorFamily;而当派生状态的计算逻辑固定时,使用 selector 即可。

@yanlele yanlele added the web框架 web 框架相关知识 label Feb 10, 2025
@yanlele yanlele added this to the milestone Feb 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
web框架 web 框架相关知识
Projects
None yet
Development

No branches or pull requests

1 participant