Bootstrap

HOW - React 状态模块化管理和按需加载(二) - jotai

一、背景

HOW - React 状态模块化管理和按需加载(一) - react-redux 我们已经简单介绍了 react 项目中状态管理的场景和 react-redux 的用法。今天我们主要来介绍一下 jotai.

二、jotai 介绍

在 React 项目中引入 Jotai 是一个不错的选择,特别是当你希望简化状态管理,同时保持高性能和较低的学习成本。Jotai 是一个小巧、灵活的状态管理库,其设计理念与 React Hooks 深度契合,非常适合组件间共享和管理状态。

以下是关于 Jotai 的介绍,以及如何在你已有的 React + TypeScript + Ant Design + React-Redux 项目中引入和使用 Jotai 的建议。

2.1 基本介绍

Jotai 的核心特点

  1. 简单且易用

    • 基于 atoms(最小状态单元)和 hooks,以最少的 API 实现状态管理。
    • 类似于 React 的 useStateuseReducer,上手非常简单。
  2. 性能优化

    • 只重新渲染依赖改变的组件,不会导致整个状态树重新计算。
    • 比较适合需要频繁更新的小粒度状态。
  3. 类型安全

    • 对于 TypeScript 支持非常友好,能够轻松推导状态类型。
  4. 高度灵活

    • 与其他状态管理库(如 Redux、MobX 等)兼容,支持渐进式引入。

在现有项目中使用 Jotai 的场景

  • 局部状态管理
    当你需要管理组件间的一些共享状态,但不想触碰 Redux 的全局状态时,可以考虑使用 Jotai。还记得我们在 HOW - React 状态模块化管理和按需加载(一) - react-redux 介绍过的 redux 想要管理非全局共享状态,使用起来还是比较繁琐的。而 jotai 则帮助优化了这个能力的使用成本。

  • 替代 React 的 Context
    Jotai 的原子模型比 React Context 更高效,避免了 Context 更新导致的组件重渲染。

  • 优化 Redux 中的局部状态
    如果 Redux 中存储了许多局部状态,可以用 Jotai 将其迁移到组件内部,提高性能。

2.1 jotai 使用

安装 Jotai

运行以下命令安装 Jotai 和其类型支持:

npm install jotai

基本使用方法

1. 创建 Atom(状态单元)

Jotai 的核心是 atom,它是状态的最小单元。

import { atom } from 'jotai';

// 定义一个数字状态
export const countAtom = atom(0);

// 定义一个派生状态(类似于 computed)
export const doubleCountAtom = atom((get) => get(countAtom) * 2);
2. 使用 Atom

使用 useAtom Hook 来读取和更新状态。

import React from 'react';
import { useAtom } from 'jotai';
import { countAtom, doubleCountAtom } from './atoms';

const Counter: React.FC = () => {
  const [count, setCount] = useAtom(countAtom); // 读取和更新 countAtom
  const [doubleCount] = useAtom(doubleCountAtom); // 读取 doubleCountAtom

  return (
    <div>
      <p>Count: {count}</p>
      <p>Double Count: {doubleCount}</p>
      <button onClick={() => setCount((prev) => prev + 1)}>Increment</button>
    </div>
  );
};

export default Counter;
3. 全局共享状态

可以将 atom 放置在单独的文件中,通过模块导入实现全局共享。

与 Ant Design 和 Redux 的结合

1. 替代局部状态的 Redux 实现

将一些不需要持久化到全局的局部状态从 Redux 中迁移到 Jotai:

import { atom } from 'jotai';

// 例如在 Modal 组件中管理显示状态
export const modalVisibleAtom = atom(false);

在组件中直接使用:

import { useAtom } from 'jotai';
import { modalVisibleAtom } from './atoms';
import { Modal, Button } from 'antd';

const MyModal: React.FC = () => {
  const [isVisible, setVisible] = useAtom(modalVisibleAtom);

  return (
    <>
      <Button onClick={() => setVisible(true)}>Open Modal</Button>
      <Modal
        title="Example Modal"
        visible={isVisible}
        onCancel={() => setVisible(false)}
        onOk={() => setVisible(false)}
      >
        <p>Modal content...</p>
      </Modal>
    </>
  );
};
2. 与 Redux 的协作

如果需要将 Redux 的状态与 Jotai 的状态联动,可以通过自定义 Atom 轻松实现:

import { atom } from 'jotai';
import { useSelector } from 'react-redux';

// 从 Redux 中获取状态并创建 Atom
export const reduxStateAtom = atom((get) => {
  const reduxState = useSelector((state) => state.someState);
  return reduxState;
});

Jotai 和 React-Redux 优劣对比

特点JotaiReact-Redux
学习曲线简单,API 少较复杂,需要配置 store 等
性能优化粒度细,依赖更新优化渲染全局订阅,手动优化
状态共享粒度局部或全局均适用适用于全局状态管理
类型支持非常友好依赖配置和工具链支持

三、总结

Jotai 非常适合在现有项目中逐步替换 Context 或优化局部状态管理,尤其是 Redux 中的一些小型状态。通过其简单的 API 和高性能的设计,你可以快速引入 Jotai,提升开发效率。

;