duxapp放棄了redux,在duxapp中區域性、全域性狀態的實現方案

少恭写代码發表於2024-11-07

全域性狀態

全域性狀態是一個很實用的功能,例如管理使用者資訊,元件間狀態共享等功能都需要用到全域性狀態,react有很多成熟的全域性狀態管理工具,但是很多寫起來太過麻煩,duxapp提供了幾種應對不同場景的全域性狀態的方案,當然如果你需要其他全域性狀態,可以自行整合

區域性全域性狀態

這種全域性狀態方案的使用場景,在於父子元件之間的狀態共享

import { contextState } from '@/duxapp'
import { Text } from '@/duxui'

const A = () => {

  return <contextState.Provider defaultValue='張三'>
    <B />
    <C />
  </contextState.Provider>
}

const B = () => {
  const [name] = contextState.useState()

  return <Text>{name}</Text>
}

const C = () => {
  const [, setName] = contextState.useState()

  return <Text onClick={() => setName('李四')}>設定名稱為李四</Text>
}

也可以在A元件中控制這個值的變化

import { contextState } from '@/duxapp'
import { Text } from '@/duxui'
import { useState } from 'react'

const A = () => {

  const [name, setName] = useState()

  return <contextState.Provider value={name}>
    <B />
    <C />
    <Text onClick={() => setName('王五')}>設定名稱為王五</Text>
  </contextState.Provider>
}

const B = () => {
  const [name] = contextState.useState()

  return <Text>{name}</Text>
}

const C = () => {
  const [, setName] = contextState.useState()

  return <Text onClick={() => setName('李四')}>設定名稱為李四</Text>
}

這裡只演示了一層元件的巢狀,多層元件的巢狀也是支援的

全域性狀態

這個狀態可以在整個執行時內所有頁面或者元件內呼叫

import { createGlobalState } from '@/duxapp'

/** 需要在合適的地方建立,然後匯出,在此處僅演示如何使用 */
const globalState = createGlobalState({ text: '預設值' })

// 任何地方設定值
globalState.setState({ text: '設定的值' })

// 在元件或者hook中取值
const data = globalState.useState()

這個方法使用比較單間,如果你需要更復雜的功能,例如使用者資訊管理,可以使用下面的全域性狀態管理

全域性狀態管理

全域性狀態管理是用 ObjectManage 這個類來實現的,你需要繼續擴充套件編寫這個類來實現功能,下面以使用者資訊管理來演示如何使用這個類

  • 定義一個使用者管理類繼承到ObjectManage
  • 透過data,編寫預設資料
  • 透過建構函式設定 ObjectManage 的引數,引數的意思是使用快取,快取資料,當你更新資料時,資料會被自動設定到本地快取中,下次啟動將自動讀取快取
import { ObjectManage } from '@/duxapp'

class UserManage extends ObjectManage {
  
  constructor() {
    super({
      cacheKey: 'userInfo',
      cache: true
    })
  }

  data = {
    // 登入狀態
    status: false,
    // ...其他模組的使用者資訊
  }
}

/**
 * 例項化這個使用者管理物件並且匯出
 */
export const user = new UserManage()

這樣就獲得了一個基本的全域性狀態,要使用這些全域性狀態,可以在元件、hook、或者其他任何位置

// 直接呼叫當前資料
user.data.status

// 使用hook呼叫資料
const data = user.useData()
data.status

要設定這些資料這樣操作

// 使用hook呼叫資料
user.set({ status: true })
// 或者使用函式
user.set(oldData => ({ ...oldData, status: true }))

對於使用者資訊管理,他還需要一些其他的操作,都可以在使用者管理類裡面進行擴充套件,例如判斷是否登入,去登入、退出登入、更新使用者資訊、獲取線上使用者資訊等

import { ObjectManage } from '@/duxapp'

class UserManage extends ObjectManage {
  
  constructor() {
    super({
      cacheKey: 'userInfo',
      cache: true
    })
  }

  data = {
    // 登入狀態
    status: false,
    // ...其他模組的使用者資訊
  }

  isLogin = () => !!this.data.status

  login = () => {
    // 登入邏輯
  }

  logout = () => {
    // 退出登入邏輯
  }

  getOnlineUserInfo = () => {
    // 請求使用者資訊介面更新使用者資訊
    request('').then(res => this.set(res))
  }

  setUsreInfo = data => {
    this.set(old => ({ ...old, ...data }))
    // 請求介面更新使用者資訊
    request({
      url: '',
      method: 'POST',
      data
    })
  }
}

/**
 * 例項化這個使用者管理物件並且匯出
 */
export const user = new UserManage()

這裡僅是舉例,使用者模組裡面的使用者管理功能遠比此例子複雜,可以前往檢視

開發文件:http://duxapp.cn

GitHub:https://github.com/duxapp

相關文章