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

目录

  • 一、背景
  • [二、jotai 介绍](#二、jotai 介绍)
    • [2.1 基本介绍](#2.1 基本介绍)
      • [Jotai 的核心特点](#Jotai 的核心特点)
      • [在现有项目中使用 Jotai 的场景](#在现有项目中使用 Jotai 的场景)
    • [2.1 jotai 使用](#2.1 jotai 使用)
      • [安装 Jotai](#安装 Jotai)
      • 基本使用方法
        • [1. 创建 Atom(状态单元)](#1. 创建 Atom(状态单元))
        • [2. 使用 Atom](#2. 使用 Atom)
        • [3. 全局共享状态](#3. 全局共享状态)
      • [与 Ant Design 和 Redux 的结合](#与 Ant Design 和 Redux 的结合)
        • [1. 替代局部状态的 Redux 实现](#1. 替代局部状态的 Redux 实现)
        • [2. 与 Redux 的协作](#2. 与 Redux 的协作)
      • [Jotai 和 React-Redux 优劣对比](#Jotai 和 React-Redux 优劣对比)
  • 三、总结

一、背景

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 和其类型支持:

bash 复制代码
npm install jotai

基本使用方法

1. 创建 Atom(状态单元)

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

typescript 复制代码
import { atom } from 'jotai';

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

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

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

typescript 复制代码
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:

typescript 复制代码
import { atom } from 'jotai';

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

在组件中直接使用:

typescript 复制代码
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 轻松实现:

typescript 复制代码
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 优劣对比

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

三、总结

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

相关推荐
Eliauk__2 分钟前
深入剖析 Vue 双向数据绑定机制 —— 从响应式原理到 v-model 实现全解析
前端·javascript·面试
代码小学僧2 分钟前
Cursor 的系统级提示词被大佬逆向出来了!一起来看看优秀 prompt是怎么写的
前端·ai编程·cursor
MrsBaek6 分钟前
前端笔记-Axios
前端·笔记
洋流9 分钟前
什么?还没弄懂关键字this?一篇文章带你速通
前端·javascript
晴殇i10 分钟前
for...in 循环的坑,别再用它遍历 JavaScript 数组了!
前端·javascript
littleplayer12 分钟前
iOS 单元测试详细讲解-DeepSeek
前端
littleplayer14 分钟前
iOS 单元测试与 UI 测试详解-DeepSeek
前端·单元测试·测试
夜熵16 分钟前
Vue中nextTick()用法
前端·面试
小桥风满袖16 分钟前
Three.js-硬要自学系列15 (圆弧顶点、几何体方法、曲线简介、圆、椭圆、样条曲线、贝塞尔曲线)
前端·css·three.js
洋流17 分钟前
JavaScript事件流机制详解:捕获、冒泡与阻止传播
前端·javascript