更強大的React 狀態(tài)管理庫Zustand使用詳解
介紹
在這篇文章中,我會介紹 Zustand 在實際項目中的使用。
我會構(gòu)建一個 GitHub 用戶搜索項目,在項目中通過調(diào)用 GitHub API 來實現(xiàn)搜索用戶的功能。我還會并演示如何直接從 Zustand 存儲中進行 API 調(diào)用,并將狀態(tài)持久化到 sessionStorage 或 localStorage 中。
完成效果如下:
創(chuàng)建項目項目
首先,我們需要創(chuàng)建一個新的 React 應用程序。
我們需要在終端中運行命令來下面的命令來創(chuàng)建項目:
npx create-react-app github-user-search --template typescript
這行命令會利用 CRA 創(chuàng)建一個常規(guī)的 typescript react 項目。
安裝項目依賴
創(chuàng)建項目后,我們需要進入該項目文件夾中。
cd github-user-search
并在終端中運行以下命令來安裝項目所需要的依賴項:
npm i zustand @chakra-ui/react @emotion/react @emotion/styled react-icons react-router-dom axios framer-motion pluralize query-string react-helmet-async react-hook-form react-paginate
- zustand:狀態(tài)管理庫。
- @chakra-ui/react:UI 庫。
- @emotion/react:CSS-in-JS 庫。
- @emotion/styled:CSS-in-JS 庫。
- react-icons:圖標庫。
- react-router-dom:路由庫。
- axios:HTTP 請求庫。
- framer-motion:動畫庫。
- pluralize:單詞處理庫。
- query-string:URL 查詢字符串庫。
- react-helmet-async:React 異步線程安全庫。
- react-hook-form:React 表單庫。
- react-paginate:React 分頁庫。
創(chuàng)建項目結(jié)構(gòu)
安裝好項目依賴后,我們需要創(chuàng)建項目所需要的目錄結(jié)構(gòu)。
項目目錄結(jié)構(gòu)如下:
src ├── index.tsx ├── assets ├── container ├── components ├── pages ├── routes ├── services ├── store └── theme
設置環(huán)境變量
創(chuàng)建項目結(jié)構(gòu)后,我們需要創(chuàng)建環(huán)境變量。
在項目根目錄中創(chuàng)建一個 .env 文件,并在其中添加以下變量:
REACT_APP_GITHUB_API_URL=https://api.github.com
服務
創(chuàng)建環(huán)境變量后,我們需要創(chuàng)建服務。
在項目的 services 文件夾中創(chuàng)建一個 githubService.ts 文件,并添加以下代碼:
import axios from 'axios'; import qs from 'query-string'; const github = axios.create({ baseURL: process.env.REACT_APP_GITHUB_API_URL, }); interface IGet { url: string; query?: Record<string, any>; } const get = async <T>({ url, query = {} }: IGet): Promise<T> => { const queryString = `?${qs.stringify(query)}`; const response = await github.get(`${url + queryString}`); return response.data; }; const methods = { get }; export default methods;
設置 store
接下來,我們將建立我們的 Github store。我們將實現(xiàn) Zutsand persist 方法來將我們的狀態(tài)持久化到 sessionStorage 或 localStorage 中。
在 stores/github.ts 中添加代碼:
import create from 'zustand'; import { stringify } from 'query-string'; import { persist } from 'zustand/middleware'; import methods from 'services/github'; import { IUserDetails, ISearchResonse, IGithubStore } from 'stores/types'; export const githubStore = create( persist<IGithubStore>( (set, get) => ({ isLoading: false, cached_users_details: [], // to cache users details query: { page: 1, per_page: 20 }, search: async (query) => { try { set(() => ({ isLoading: true })); window.history.pushState('', '', `?${stringify(query)}`); const data = await methods.get<ISearchResonse>({ url: '/search/users', query, }); set(() => ({ data, query, isLoading: false })); } catch (err: any) { const error = err?.message || err?.data?.message || 'Unexpected network error.'; set(() => ({ isLoading: false, error })); } }, getUser: async (username) => { try { set(() => ({ isLoading: true })); // check if user is already cached const userDetails = get().cached_users_details.find( (u) => u.login === username ); if (userDetails) { set(() => ({ userDetails, isLoading: false })); } else { const userInfo = await methods.get<IUserDetails>({ url: `/users/${username}`, }); set((state) => ({ cached_users_details: [...state.cached_users_details, userInfo], userDetails: userInfo, isLoading: false, })); } } catch (err: any) { const error = err?.message || err?.data?.message || 'Unexpected network error.'; set(() => ({ isLoading: false, error })); } }, }), { name: 'search-storage', getStorage: () => sessionStorage, } ) );
我們能夠?qū)?GitHub api 進行異步調(diào)用,并直接從我們的 store 很好地處理響應,而無需使用額外的中間件。
我們還緩存了我們的用戶詳細信息,這樣我們就不必再次調(diào)用 API 來再次獲取相同的用戶詳細信息。我們還將我們的狀態(tài)持久化到會話存儲中。
我們還可以通過將 getStorage 方法的返回值更改為 localStorage,來將我們的狀態(tài)持久化到 localStorage 中。
清除/重置存儲
目前,Zustand 沒有關于清除/重置存儲開箱即用的方法。
我們可以通過向我們的 store 添加一個 clear/reset 方法,將我們的狀態(tài)重置回初始狀態(tài)并調(diào)用 sessionStorage 或 localStorage clear() 方法保持數(shù)據(jù)的同步。
const initialState = { data: undefined, userDetails: undefined, cached_users_details: [], query: { page: 1, per_page: 20 }, isLoading: false, error: undefined, }; export const githubStore = create( persist<IGithubStore>( (set, get) => ({ ...initialState, ... clear: () => { set(() => (initialState)); sessionStorage.clear(); // or localStorage.clear(); }, }) ) );
本文主要關注的是 Zustand 狀態(tài)管理部分,UI 部分就不展開了。
以上就是更強大的React 狀態(tài)管理庫Zustand使用詳解的詳細內(nèi)容,更多關于React 狀態(tài)管理庫Zustand的資料請關注腳本之家其它相關文章!
相關文章
react+axios實現(xiàn)github搜索用戶功能(示例代碼)
這篇文章主要介紹了react+axios實現(xiàn)搜索github用戶功能,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-09-09