前端状态管理:别让你的状态变成一团乱麻

前端状态管理:别让你的状态变成一团乱麻

毒舌时刻

这状态管理得跟蜘蛛网似的,谁能理得清?

各位前端同行,咱们今天聊聊前端状态管理。别告诉我你还在使用 setState 管理所有状态,那感觉就像在没有地图的情况下寻宝——能找,但累死你。

为什么你需要状态管理

最近看到一个项目,组件之间传递状态需要经过 5 层,修改一个状态要修改多个地方。我就想问:你是在做状态管理还是在做传递游戏?

反面教材

// 反面教材:混乱的状态管理 function App() { const [user, setUser] = useState(null); const [posts, setPosts] = useState([]); const [comments, setComments] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { async function fetchData() { setLoading(true); try { const userResponse = await fetch('/api/user'); const userData = await userResponse.json(); setUser(userData); const postsResponse = await fetch('/api/posts'); const postsData = await postsResponse.json(); setPosts(postsData); const commentsResponse = await fetch('/api/comments'); const commentsData = await commentsResponse.json(); setComments(commentsData); } catch (error) { console.error('Error fetching data:', error); } finally { setLoading(false); } } fetchData(); }, []); return ( <div> {loading ? <div>加载中...</div> : ( <div> <UserHeader user={user} /> <PostList posts={posts} comments={comments} /> </div> )} </div> ); } function UserHeader({ user }) { return <h1>Welcome, {user?.name}</h1>; } function PostList({ posts, comments }) { return ( <div> {posts.map(post => ( <div key={post.id}> <h2>{post.title}</h2> <p>{post.content}</p> <CommentList postId={post.id} comments={comments} /> </div> ))} </div> ); } function CommentList({ postId, comments }) { const postComments = comments.filter(comment => comment.postId === postId); return ( <div> {postComments.map(comment => ( <div key={comment.id}>{comment.content}</div> ))} </div> ); } 

毒舌点评:这状态管理,就像在玩传球游戏,球传来传去都不知道传到哪里了。

正确姿势

1. Redux Toolkit

// 正确姿势:Redux Toolkit // 1. 安装依赖 // npm install @reduxjs/toolkit react-redux // 2. 创建 store // store/index.js import { configureStore } from '@reduxjs/toolkit'; import userReducer from './slices/userSlice'; import postsReducer from './slices/postsSlice'; import commentsReducer from './slices/commentsSlice'; export const store = configureStore({ reducer: { user: userReducer, posts: postsReducer, comments: commentsReducer, }, }); // 3. 创建 slices // store/slices/userSlice.js import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; export const fetchUser = createAsyncThunk('user/fetchUser', async () => { const response = await fetch('/api/user'); return response.json(); }); const userSlice = createSlice({ name: 'user', initialState: { data: null, loading: false, error: null, }, reducers: {}, extraReducers: (builder) => { builder .addCase(fetchUser.pending, (state) => { state.loading = true; state.error = null; }) .addCase(fetchUser.fulfilled, (state, action) => { state.loading = false; state.data = action.payload; }) .addCase(fetchUser.rejected, (state, action) => { state.loading = false; state.error = action.error.message; }); }, }); export default userSlice.reducer; // 4. 使用 store // index.js import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; import { Provider } from 'react-redux'; import { store } from './store'; ReactDOM.createRoot(document.getElementById('root')).render( <Provider store={store}> <App /> </Provider> ); // 5. 使用状态 // App.jsx import React, { useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { fetchUser } from './store/slices/userSlice'; import { fetchPosts } from './store/slices/postsSlice'; import { fetchComments } from './store/slices/commentsSlice'; import UserHeader from './components/UserHeader'; import PostList from './components/PostList'; function App() { const dispatch = useDispatch(); const { loading } = useSelector((state) => state.user); useEffect(() => { dispatch(fetchUser()); dispatch(fetchPosts()); dispatch(fetchComments()); }, [dispatch]); return ( <div> {loading ? <div>加载中...</div> : ( <div> <UserHeader /> <PostList /> </div> )} </div> ); } // components/UserHeader.jsx import React from 'react'; import { useSelector } from 'react-redux'; function UserHeader() { const user = useSelector((state) => state.user.data); return <h1>Welcome, {user?.name}</h1>; } export default UserHeader; // components/PostList.jsx import React from 'react'; import { useSelector } from 'react-redux'; import CommentList from './CommentList'; function PostList() { const posts = useSelector((state) => state.posts.data); return ( <div> {posts.map(post => ( <div key={post.id}> <h2>{post.title}</h2> <p>{post.content}</p> <CommentList postId={post.id} /> </div> ))} </div> ); } export default PostList; // components/CommentList.jsx import React from 'react'; import { useSelector } from 'react-redux'; function CommentList({ postId }) { const comments = useSelector((state) => state.comments.data.filter(comment => comment.postId === postId) ); return ( <div> {comments.map(comment => ( <div key={comment.id}>{comment.content}</div> ))} </div> ); } export default CommentList; 

2. Zustand

// 正确姿势:Zustand // 1. 安装依赖 // npm install zustand // 2. 创建 store // store/index.js import { create } from 'zustand'; import { persist } from 'zustand/middleware'; const useStore = create( persist( (set, get) => ({ user: null, posts: [], comments: [], loading: false, error: null, fetchUser: async () => { set({ loading: true, error: null }); try { const response = await fetch('/api/user'); const data = await response.json(); set({ user: data, loading: false }); } catch (error) { set({ error: error.message, loading: false }); } }, fetchPosts: async () => { set({ loading: true, error: null }); try { const response = await fetch('/api/posts'); const data = await response.json(); set({ posts: data, loading: false }); } catch (error) { set({ error: error.message, loading: false }); } }, fetchComments: async () => { set({ loading: true, error: null }); try { const response = await fetch('/api/comments'); const data = await response.json(); set({ comments: data, loading: false }); } catch (error) { set({ error: error.message, loading: false }); } }, }), { name: 'app-storage', } ) ); export default useStore; // 3. 使用 store // App.jsx import React, { useEffect } from 'react'; import useStore from './store'; import UserHeader from './components/UserHeader'; import PostList from './components/PostList'; function App() { const { loading, fetchUser, fetchPosts, fetchComments } = useStore(); useEffect(() => { fetchUser(); fetchPosts(); fetchComments(); }, [fetchUser, fetchPosts, fetchComments]); return ( <div> {loading ? <div>加载中...</div> : ( <div> <UserHeader /> <PostList /> </div> )} </div> ); } // components/UserHeader.jsx import React from 'react'; import useStore from '../store'; function UserHeader() { const user = useStore((state) => state.user); return <h1>Welcome, {user?.name}</h1>; } export default UserHeader; // components/PostList.jsx import React from 'react'; import useStore from '../store'; import CommentList from './CommentList'; function PostList() { const posts = useStore((state) => state.posts); return ( <div> {posts.map(post => ( <div key={post.id}> <h2>{post.title}</h2> <p>{post.content}</p> <CommentList postId={post.id} /> </div> ))} </div> ); } export default PostList; // components/CommentList.jsx import React from 'react'; import useStore from '../store'; function CommentList({ postId }) { const comments = useStore((state) => state.comments.filter(comment => comment.postId === postId) ); return ( <div> {comments.map(comment => ( <div key={comment.id}>{comment.content}</div> ))} </div> ); } export default CommentList; 

3. Jotai

// 正确姿势:Jotai // 1. 安装依赖 // npm install jotai // 2. 创建 atoms // store/atoms.js import { atom, useAtom, useAtomValue, useSetAtom } from 'jotai'; import { atomWithStorage } from 'jotai/utils'; // 状态 atoms const userAtom = atomWithStorage('user', null); const postsAtom = atomWithStorage('posts', []); const commentsAtom = atomWithStorage('comments', []); const loadingAtom = atom(false); const errorAtom = atom(null); // 动作 atoms const fetchUserAtom = atom( null, async (_, set) => { set(loadingAtom, true); set(errorAtom, null); try { const response = await fetch('/api/user'); const data = await response.json(); set(userAtom, data); } catch (error) { set(errorAtom, error.message); } finally { set(loadingAtom, false); } } ); const fetchPostsAtom = atom( null, async (_, set) => { set(loadingAtom, true); set(errorAtom, null); try { const response = await fetch('/api/posts'); const data = await response.json(); set(postsAtom, data); } catch (error) { set(errorAtom, error.message); } finally { set(loadingAtom, false); } } ); const fetchCommentsAtom = atom( null, async (_, set) => { set(loadingAtom, true); set(errorAtom, null); try { const response = await fetch('/api/comments'); const data = await response.json(); set(commentsAtom, data); } catch (error) { set(errorAtom, error.message); } finally { set(loadingAtom, false); } } ); export { userAtom, postsAtom, commentsAtom, loadingAtom, errorAtom, fetchUserAtom, fetchPostsAtom, fetchCommentsAtom }; // 3. 使用 atoms // App.jsx import React, { useEffect } from 'react'; import { useAtomValue, useSetAtom } from 'jotai'; import { loadingAtom, fetchUserAtom, fetchPostsAtom, fetchCommentsAtom } from './store/atoms'; import UserHeader from './components/UserHeader'; import PostList from './components/PostList'; function App() { const loading = useAtomValue(loadingAtom); const fetchUser = useSetAtom(fetchUserAtom); const fetchPosts = useSetAtom(fetchPostsAtom); const fetchComments = useSetAtom(fetchCommentsAtom); useEffect(() => { fetchUser(); fetchPosts(); fetchComments(); }, [fetchUser, fetchPosts, fetchComments]); return ( <div> {loading ? <div>加载中...</div> : ( <div> <UserHeader /> <PostList /> </div> )} </div> ); } // components/UserHeader.jsx import React from 'react'; import { useAtomValue } from 'jotai'; import { userAtom } from '../store/atoms'; function UserHeader() { const user = useAtomValue(userAtom); return <h1>Welcome, {user?.name}</h1>; } export default UserHeader; // components/PostList.jsx import React from 'react'; import { useAtomValue } from 'jotai'; import { postsAtom } from '../store/atoms'; import CommentList from './CommentList'; function PostList() { const posts = useAtomValue(postsAtom); return ( <div> {posts.map(post => ( <div key={post.id}> <h2>{post.title}</h2> <p>{post.content}</p> <CommentList postId={post.id} /> </div> ))} </div> ); } export default PostList; // components/CommentList.jsx import React from 'react'; import { useAtomValue } from 'jotai'; import { commentsAtom } from '../store/atoms'; function CommentList({ postId }) { const comments = useAtomValue(commentsAtom); const postComments = comments.filter(comment => comment.postId === postId); return ( <div> {postComments.map(comment => ( <div key={comment.id}>{comment.content}</div> ))} </div> ); } export default CommentList; 

毒舌点评:这才叫前端状态管理,集中管理状态,组件之间共享状态,再也不用担心状态传递的问题了。

Read more

AI界的“四大天王”:AIGC、RAG、Agent、MCP

本文系统介绍了AI大模型技术演进,从AIGC的单模态、多模态特性,到解决实时性问题的RAG技术,再到赋予AI工具使用能力的Function Calling。进一步探讨了智能体Agent的闭环工作流程,以及MCP协议作为标准化接口如何解决AI应用生态整合难题,为AI技术发展提供统一框架。 一、前言 为啥我会写这篇文章?是因为我前几天看到一个报告,报告显示,大部分人还只是停留在简单与模型对话,甚至只有2%的人开发过智能体,更离谱的是30%多仅仅是听说过。表明整体AI技能基础相对薄弱。 技术圈针对AI已经到了疯癫的程度,这份报告颠覆了我之前的看法,以为AI如干柴烈火之势的发展,大家应该或多或少都知道一些相关的知识,但在技术圈往往会出现幸存者偏差,所以老周得出来写一篇AI相关技术的普及知识。 随着AI技术发展迅猛,日新月异。大语言模型(LLM)、AIGC、多模态、RAG、Agent、MCP等各种相关概念层出不穷,极易混淆。我 这次不讲太多原理性的东西,作为技术科普文来聊一聊这其中的关系。 二、AIGC 2.1 单模态 我们大部分人都是从ChatGPT问世开始接触AI的。刚开始

2026 Python+AI入门|0基础速通,吃透热门轻量化玩法

2026 Python+AI入门|0基础速通,吃透热门轻量化玩法

🎁个人主页:User_芊芊君子 🎉欢迎大家点赞👍评论📝收藏⭐文章 🔍系列专栏:AI 文章目录: * 一、2026 Python+AI入门,必抓3个热门新趋势 * 二、入门前提:不用啃硬骨头,掌握这2点就够了 * 环境搭建(10分钟搞定,Windows/Mac通用) * 三、3个实战案例 * 案例1:30行代码开发AI文本总结工具(轻量化工具,最易上手) * 案例2:大模型微调入门(Llama 3微调,2026热门) * 案例3:AI自动数据标注(图像标注,企业刚需) * 四、Python+AI入门学习流程图(2026最新,不绕路) * 五、2026新手避坑指南 * 六、总结 【前言】 大家好,我是一名深耕AI入门教学的开发者,

人工智能:自然语言处理在金融领域的应用与实战

人工智能:自然语言处理在金融领域的应用与实战

人工智能:自然语言处理在金融领域的应用与实战 学习目标 💡 理解自然语言处理(NLP)在金融领域的应用场景和重要性 💡 掌握金融领域NLP应用的核心技术(如文本分类、情感分析、风险评估) 💡 学会使用前沿模型(如BERT、GPT-3)进行金融文本分析 💡 理解金融领域的特殊挑战(如金融术语、数据噪声、实时性要求高) 💡 通过实战项目,开发一个金融风险评估应用 重点内容 * 金融领域NLP应用的主要场景 * 核心技术(文本分类、情感分析、风险评估) * 前沿模型(BERT、GPT-3)在金融领域的使用 * 金融领域的特殊挑战 * 实战项目:金融风险评估应用开发 一、金融领域NLP应用的主要场景 1.1 文本分类 1.1.1 文本分类的基本概念 文本分类是对金融文本进行分类的过程。在金融领域,文本分类的主要应用场景包括: * 新闻分类:对金融新闻进行分类(如“股票新闻”、“债券新闻”

「源力觉醒 创作者计划」实测解析!文心一言 4.5 开源版本地化部署的表现与潜力

「源力觉醒 创作者计划」实测解析!文心一言 4.5 开源版本地化部署的表现与潜力

引言 2025 年 6 月 30 日,百度文心大模型 4.5 系列正式开源,并首发于 GitCode 平台!这一重磅消息在 AI 领域掀起了不小的波澜。作为国内最早布局大模型研发的企业之一,百度所推出的文心大模型目前已跻身国内顶级大模型行列,此次开源无疑将对各行各业产生深远影响,进一步加速大模型的发展进程。接下来,就让我们一同探究文心一言 4.5 开源版本地化部署的表现与潜力。 文章目录 * 引言 * 一、文心大模型 ERNIE 4.5 开源介绍 * 1.1 开源版本介绍 * 1.1 ERNIE 4.5 的主要特点和区别 * 二、文心ERNIE 4.5 技术解析 * 2.1