关键词:Recoil selector
在 Recoil 中,selector 用于创建派生状态,它可以根据一个或多个原子(atom)状态计算出新的状态。selector 的值会自动进行记忆化,只有当依赖的状态发生变化时才会重新计算。下面详细介绍 selector 的使用方法。
1. 基本使用
创建一个简单的 atom 和 selector:
import React from "react";
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 = () => {
// 使用 useRecoilValue 钩子获取 selector 的值
const textLength = useRecoilValue(textLengthState);
return (
<div>
<p>Text length: {textLength}</p>
</div>
);
};
export default App;在上述代码中:
- 首先定义了一个
atomtextState,它代表一个文本状态。 - 然后定义了一个
selectortextLengthState,在get函数中,通过get参数获取textState的值,并计算其长度。 - 最后在组件中使用
useRecoilValue钩子获取textLengthState的值并渲染。
2. 多个依赖的 selector
selector 可以依赖多个 atom 或其他 selector:
import React from "react";
import { atom, selector, useRecoilValue } from "recoil";
// 定义两个原子状态
const num1State = atom({
key: "num1State",
default: 10,
});
const num2State = atom({
key: "num2State",
default: 20,
});
// 定义一个 selector,依赖于 num1State 和 num2State
const sumState = selector({
key: "sumState",
get: ({ get }) => {
const num1 = get(num1State);
const num2 = get(num2State);
return num1 + num2;
},
});
const App = () => {
const sum = useRecoilValue(sumState);
return (
<div>
<p>Sum: {sum}</p>
</div>
);
};
export default App;在这个例子中,sumState 这个 selector 依赖于 num1State 和 num2State 两个 atom,它会计算这两个状态的和。
3. 可写的 selector
除了只读的 selector,还可以创建可写的 selector,通过 set 函数来修改依赖的状态:
import React from "react";
import { atom, selector, useRecoilState } from "recoil";
// 定义一个原子状态
const counterState = atom({
key: "counterState",
default: 0,
});
// 定义一个可写的 selector
const doubleCounterState = selector({
key: "doubleCounterState",
get: ({ get }) => {
const counter = get(counterState);
return counter * 2;
},
set: ({ set }, newValue) => {
set(counterState, newValue / 2);
},
});
const App = () => {
const [doubleCounter, setDoubleCounter] = useRecoilState(doubleCounterState);
return (
<div>
<p>Double Counter: {doubleCounter}</p>
<button onClick={() => setDoubleCounter(doubleCounter + 2)}>Increment Double</button>
</div>
);
};
export default App;在这个例子中,doubleCounterState 是一个可写的 selector:
get函数根据counterState计算出双倍的值。set函数接收一个新值,并将其除以 2 后更新counterState。
4. 使用多个 selector 组合状态
可以将多个 selector 组合起来创建更复杂的派生状态:
import React from "react";
import { atom, selector, useRecoilValue } from "recoil";
// 定义原子状态
const priceState = atom({
key: "priceState",
default: 100,
});
const discountRateState = atom({
key: "discountRateState",
default: 0.1,
});
// 定义第一个 selector,计算折扣金额
const discountAmountState = selector({
key: "discountAmountState",
get: ({ get }) => {
const price = get(priceState);
const discountRate = get(discountRateState);
return price * discountRate;
},
});
// 定义第二个 selector,计算最终价格
const finalPriceState = selector({
key: "finalPriceState",
get: ({ get }) => {
const price = get(priceState);
const discountAmount = get(discountAmountState);
return price - discountAmount;
},
});
const App = () => {
const finalPrice = useRecoilValue(finalPriceState);
return (
<div>
<p>Final Price: {finalPrice}</p>
</div>
);
};
export default App;在这个例子中,discountAmountState 计算折扣金额,finalPriceState 依赖于 priceState 和 discountAmountState 计算最终价格。