Atom配置 #
Atom 完整配置 #
jsx
const myAtom = atom({
key: 'myAtom',
default: initialValue,
dangerouslyAllowMutability: false,
effects: [
effect1,
effect2,
],
});
配置选项详解 #
key #
key 是 Atom 的唯一标识符,必须全局唯一。
jsx
const countState = atom({
key: 'countState',
default: 0,
});
const userCountState = atom({
key: 'userCountState',
default: 0,
});
命名建议:
jsx
const [entity][State] = atom({
key: '[entity][State]',
default: ...,
});
const todoListState = atom({
key: 'todoListState',
default: [],
});
const userSettingsState = atom({
key: 'userSettingsState',
default: {},
});
default #
default 定义 Atom 的默认值。
静态值 #
jsx
const countState = atom({
key: 'countState',
default: 0,
});
const userState = atom({
key: 'userState',
default: {
name: '',
email: '',
},
});
Promise 或异步值 #
jsx
const dataState = atom({
key: 'dataState',
default: fetch('/api/data').then(r => r.json()),
});
引用另一个 Atom #
jsx
const baseState = atom({
key: 'baseState',
default: 'hello',
});
const derivedState = atom({
key: 'derivedState',
default: baseState,
});
dangerouslyAllowMutability #
默认情况下,Recoil 要求状态是不可变的。如果需要直接修改对象,可以设置此选项:
jsx
const mutableState = atom({
key: 'mutableState',
default: { count: 0 },
dangerouslyAllowMutability: true,
});
function Component() {
const [state, setState] = useRecoilState(mutableState);
const mutate = () => {
state.count++;
setState(state);
};
return <button onClick={mutate}>{state.count}</button>;
}
警告:不推荐使用此选项,可能导致不可预期的行为。
Atom Effects #
Atom Effects 是在 Atom 创建时执行的副作用函数,用于处理副作用。
基本结构 #
jsx
const myAtom = atom({
key: 'myAtom',
default: 0,
effects: [
(param) => {
console.log('Atom created:', param.node.key);
return () => {
console.log('Atom cleanup');
};
},
],
});
Effects 参数 #
jsx
effects: [
({
node,
trigger,
setSelf,
resetSelf,
onSet,
getPromise,
getLoadable,
getInfo_UNSTABLE,
}) => {
},
]
| 参数 | 类型 | 说明 |
|---|---|---|
node |
RecoilState | 当前 Atom 的引用 |
trigger |
‘get’ | ‘set’ | 触发方式 |
setSelf |
function | 设置初始值 |
resetSelf |
function | 重置到默认值 |
onSet |
function | 监听值变化 |
getPromise |
function | 异步获取其他状态 |
getLoadable |
function | 同步获取其他状态 |
常见使用场景 #
1. 日志记录 #
jsx
const logEffect = ({ node, onSet }) => {
onSet((newValue, oldValue) => {
console.log(`[${node.key}]`, oldValue, '->', newValue);
});
};
const countState = atom({
key: 'countState',
default: 0,
effects: [logEffect],
});
2. 本地存储持久化 #
jsx
const localStorageEffect = (key) => ({ setSelf, onSet }) => {
const savedValue = localStorage.getItem(key);
if (savedValue != null) {
setSelf(JSON.parse(savedValue));
}
onSet((newValue, _, isReset) => {
isReset
? localStorage.removeItem(key)
: localStorage.setItem(key, JSON.stringify(newValue));
});
};
const todoListState = atom({
key: 'todoListState',
default: [],
effects: [localStorageEffect('todos')],
});
3. Session 存储 #
jsx
const sessionStorageEffect = (key) => ({ setSelf, onSet }) => {
const savedValue = sessionStorage.getItem(key);
if (savedValue != null) {
setSelf(JSON.parse(savedValue));
}
onSet((newValue, _, isReset) => {
isReset
? sessionStorage.removeItem(key)
: sessionStorage.setItem(key, JSON.stringify(newValue));
});
};
const formDataState = atom({
key: 'formDataState',
default: {},
effects: [sessionStorageEffect('form_data')],
});
4. 历史记录 #
jsx
const historyEffect = ({ onSet }) => {
const history = [];
onSet((newValue, oldValue) => {
history.push({ oldValue, newValue, timestamp: Date.now() });
console.log('History:', history);
});
};
const textState = atom({
key: 'textState',
default: '',
effects: [historyEffect],
});
5. 验证 #
jsx
const validationEffect = ({ onSet, setSelf }) => {
onSet((newValue) => {
if (newValue < 0) {
setSelf(0);
console.warn('Value cannot be negative, reset to 0');
}
});
};
const countState = atom({
key: 'countState',
default: 0,
effects: [validationEffect],
});
6. 同步其他状态 #
jsx
const syncEffect = ({ onSet, setSelf, getPromise }) => {
onSet(async (newValue) => {
const otherValue = await getPromise(otherState);
console.log('Other state:', otherValue);
});
};
7. API 同步 #
jsx
const apiSyncEffect = ({ onSet, setSelf }) => {
onSet(async (newValue) => {
try {
await fetch('/api/save', {
method: 'POST',
body: JSON.stringify(newValue),
});
} catch (error) {
console.error('Failed to save:', error);
}
});
};
const settingsState = atom({
key: 'settingsState',
default: {},
effects: [apiSyncEffect],
});
组合多个 Effects #
jsx
const userState = atom({
key: 'userState',
default: null,
effects: [
localStorageEffect('user'),
logEffect,
validationEffect,
],
});
TypeScript 类型定义 #
基本类型 #
tsx
import { atom } from 'recoil';
const countState = atom<number>({
key: 'countState',
default: 0,
});
const textState = atom<string>({
key: 'textState',
default: '',
});
对象类型 #
tsx
interface User {
id: number;
name: string;
email: string;
}
const userState = atom<User | null>({
key: 'userState',
default: null,
});
数组类型 #
tsx
interface Todo {
id: number;
text: string;
completed: boolean;
}
const todoListState = atom<Todo[]>({
key: 'todoListState',
default: [],
});
Effects 类型 #
tsx
import { AtomEffect } from 'recoil';
const localStorageEffect = <T>(key: string): AtomEffect<T> => ({
setSelf,
onSet,
}) => {
const savedValue = localStorage.getItem(key);
if (savedValue != null) {
setSelf(JSON.parse(savedValue) as T);
}
onSet((newValue) => {
localStorage.setItem(key, JSON.stringify(newValue));
});
};
const todoListState = atom<Todo[]>({
key: 'todoListState',
default: [],
effects: [localStorageEffect<Todo[]>('todos')],
});
完整示例 #
jsx
import { atom, useRecoilState } from 'recoil';
const localStorageEffect = (key) => ({ setSelf, onSet }) => {
const savedValue = localStorage.getItem(key);
if (savedValue != null) {
setSelf(JSON.parse(savedValue));
}
onSet((newValue, _, isReset) => {
isReset
? localStorage.removeItem(key)
: localStorage.setItem(key, JSON.stringify(newValue));
});
};
const logEffect = ({ node, onSet }) => {
onSet((newValue, oldValue) => {
console.log(`[${node.key}]`, { oldValue, newValue });
});
};
const validationEffect = ({ onSet, setSelf }) => {
onSet((newValue) => {
if (newValue.text?.length > 100) {
setSelf({ ...newValue, text: newValue.text.slice(0, 100) });
}
});
};
const noteState = atom({
key: 'noteState',
default: {
id: null,
text: '',
createdAt: null,
},
effects: [
localStorageEffect('note'),
logEffect,
validationEffect,
],
});
function NoteEditor() {
const [note, setNote] = useRecoilState(noteState);
const handleChange = (e) => {
setNote({
...note,
text: e.target.value,
updatedAt: Date.now(),
});
};
return (
<div>
<textarea
value={note.text}
onChange={handleChange}
maxLength={100}
/>
<p>{note.text.length}/100</p>
</div>
);
}
总结 #
本章学习了 Atom 的高级配置:
| 配置 | 说明 |
|---|---|
key |
唯一标识符 |
default |
默认值 |
dangerouslyAllowMutability |
允许直接修改对象 |
effects |
副作用函数数组 |
下一步,让我们学习 Atom家族,了解如何动态创建多个相关 Atom。
最后更新:2026-03-28