React18状态管理方案之Recoil

556 阅读4分钟

Recoil 是一个用于管理 React 应用程序状态的状态管理库。它提供了一种简单而灵活的方式来存储和访问状态,使得我们可以在不同组件之间共享状态,同时保持良好的性能。以下是 Recoil 的一些核心概念和特性:recoiljs中文文档 注意:一下是Facebook 的内部项目迁移但是不影响使用。

image.png

Recoil 和 Jotai 都是 React 状态管理库,但它们的设计哲学和使用场景有所不同。以下是一些可能导致开发者或团队选择 Jotai 而不是 Recoil 的原因:jotai文档,下一篇章我会单独介绍这个jotai

  1. 简洁性和易用性:Jotai 的 API 非常简单,易于理解和使用。它使用原子状态的概念,允许开发者直接创建和管理状态,减少了学习和使用的复杂性。
  2. 灵活性:Jotai 提供了更大的灵活性,支持原子状态的组合和复用,允许开发者根据需求自由构建状态管理的结构。
  3. 性能:Jotai 在性能上的表现也是一个吸引人的特性,尤其是在管理大量状态时,其细粒度的更新机制可以有效减少不必要的渲染。
  4. 响应式和简约:Jotai 的响应式设计使得状态的变化能够被快速捕捉并更新,这为构建复杂的交互提供了便利,同时保持了代码的简约性。
  5. 社区和生态系统:虽然 Recoil 和 Jotai 都有活跃的社区,但开发者可能会根据项目需求和社区支持的情况选择更适合的库。
  6. 特性差异:不同的状态管理库可能会提供不同的特性和解决方案。开发者可能会选择 Jotai 是因为它满足了他们特定的需求,比如更好的类型支持或异步状态管理的功能。

总之,选择使用哪个状态管理库通常取决于项目的具体需求、团队的熟悉程度以及对库特性的偏好。无论是 Recoil 还是 Jotai,各自都有其优点和适用场景。

Recoil 安装

pnpm add recoil

task 任务列表demo (使用Recoil演示"antd": "^5.21.1","react": "^18.3.1","recoil": "^0.7.7","typescript": "^5.6.3"

// TaskList.tsx
import React, { useState } from 'react';
// recoil基本使用
import { atom,useRecoilState } from 'recoil';
import { List, Input, Button } from 'antd';

interface Task {
  id: number;
  content: string;
}

const taskListState = atom<Task[]>({
  key: 'taskListState',
  default: [],
});

const TaskList: React.FC = () => {
    const [taskList, setTaskList] = useRecoilState(taskListState);
    const [taskContent, setTaskContent] = useState<string>('');

    const addTask = () => {
        if (taskContent.trim() !== '') {
            const newTask: Task = {
                id: Date.now(),
                content: taskContent,
            };
            setTaskList([...taskList, newTask]);
            setTaskContent('');
        }
    };

    const removeTask = (id: number) => {
        setTaskList(taskList.filter(task => task.id !== id));
    };

    return (
        <div style={{ padding: '20px' }}>
            <Input 
                value={taskContent} 
                onChange={(e) => setTaskContent(e.target.value)} 
                placeholder="输入任务"
                style={{ width: '300px', marginRight: '10px' }} 
            />
            <Button type="primary" onClick={addTask}>添加任务</Button>
            <List
                header={<div>任务列表</div>}
                bordered
                dataSource={taskList}
                renderItem={(task) => (
                    <List.Item>
                        {task.content}
                        <Button type="primary" onClick={() => removeTask(task.id)} style={{ marginLeft: '10px' }}>删除</Button>
                    </List.Item>
                )}
                style={{ marginTop: '20px' }}
            />
        </div>
    );
};

export default TaskList;
// App.tsx
import React from 'react';
import { RecoilRoot } from 'recoil';
import { Layout } from 'antd';
import TaskList from './TaskList';

const App: React.FC = () => {
    return (
        <RecoilRoot>
            <Layout style={{ padding: '20px' }}>
                <Layout.Content>
                    <h1>任务管理器</h1>
                    <TaskList />
                </Layout.Content>
            </Layout>
        </RecoilRoot>
    );
};

export default App;

效果

image.png

1. 原子(Atom)

原子是 Recoil 状态的基本单元,它代表应用中的一个状态片段。原子的状态可以被多个组件共享和更新。你可以将其视为一个可读写的状态容器。创建原子时,需要定义一个唯一的键和初始状态。

import { atom } from 'recoil';

export const exampleState = atom({
    key: 'exampleState', // 唯一标识
    default: [], // 初始状态
});

2. 选择器(Selector)

选择器是一个可以派生状态的函数。它可以通过计算原子的值生成新状态,或者从其他选择器中获取状态。选择器使得我们可以在不直接操作原子状态的情况下获取衍生状态。

import { selector } from 'recoil';
import { exampleState } from './atoms';

export const exampleCountSelector = selector({
    key: 'exampleCountSelector',
    get: ({ get }) => {
        const items = get(exampleState);
        return items.length; // 返回当前状态的长度
    },
});

3. 状态挂钩(Hooks)

Recoil 提供了几个钩子来读写状态:

  • useRecoilState: 读写原子的状态
  • useRecoilValue: 只读取状态
  • useSetRecoilState: 只设置状态
  • useRecoilCallback: 访问和修改 Recoil 状态的回调函数
import { useRecoilState } from 'recoil';
import { exampleState } from './atoms';

const ExampleComponent = () => {
    const [items, setItems] = useRecoilState(exampleState);

    const addItem = (newItem) => {
        setItems([...items, newItem]);
    };

    return (
        // 组件内容...
    );
};

4. 性能优化

Recoil 采用了细粒度的状态更新策略,这意味着只有直接依赖于被更改状态的组件会重渲染,从而提高了性能。在大型应用中,这种性能优化带来了明显的优势。

5. 异步状态管理

Recoil 的选择器可以处理异步数据。你可以在选择器中进行 API 请求或其他异步操作,并将结果存储在 Recoil 状态中。

总结

Recoil 提供了一种简单、灵活的状态管理解决方案,适用于需要跨多个组件共享状态的复杂 React 应用。通过原子和选择器的组合,你可以非常有效地组织和管理你的应用状态,保持组件的独立性和清晰性。