07-zustand

Zustand Documentationopen in new window

1. basic

import {create} from 'zustand';

// 1. 创建 store
// 语法容易出错
//   1. 函数参数必须返回一个对象,对象内部编写状态数据和方法
//   2. set 是用来修改数据的专门方法必须调用它来修改数据
// 语法1:参数是函数,需要用到老数据的场景
// 语法2:参数直接是一个对象 set({ count: 100 })
const useStore = create((set) => {
  return {
    // 状态数据
    count: 0,
    // 修改状态数据的方法
    inc: () => set((state) => ({count: state.count + 1}))
  };
});

// 2. 绑定 store 到组件
// useStore() 返回对象
function App() {
  const {count, inc} = useStore();
  return (
      <>
        <button onClick={inc}>{count}</button>
      </>
  );
}

export default App;








 











 


 





2. 异步支持

对于异步操作的支持不需要特殊的操作,直接在函数中编写异步逻辑,最后把接口的数据放到 set 函数中返回即可

import {useEffect} from 'react'
import {create} from "zustand";

const URL = 'http://geek.itheima.net/v1_0/channels'

const useStore = create((set) => {
  return {
    count: 0,
    ins: () => {
      return set(state => ({count: state.count + 1}))
    },
    channelList: [],
    fetchChannelList: async () => {
      const res = await fetch(URL)
      const jsonData = await res.json()
      set({channelList: jsonData.data.channels})
    }
  }
})

function App() {
  const {channelList, fetchChannelList} = useStore()

  useEffect(() => {
    fetchChannelList()
  }, [fetchChannelList])

  return (
      <ul>
        {channelList.map((item) => (
            <li key={item.id}>{item.name}</li>
        ))}
      </ul>
  )
}

export default App












 
 










 












{
  "data": {
    "channels": [
      {"id":0,"name":"推荐"},{"id":1,"name":"html"},{"id":2,"name":"开发者资讯"},{"id":4,"name":"c++"},
      {"id":6,"name":"css"},{"id":7,"name":"数据库"},{"id":8,"name":"区块链"},{"id":9,"name":"go"},
      {"id":10,"name":"产品"},{"id":11,"name":"后端"},{"id":12,"name":"linux"},{"id":13,"name":"人工智能"},
      {"id":14,"name":"php"},{"id":15,"name":"javascript"},{"id":16,"name":"架构"},{"id":17,"name":"前端"},
      {"id":18,"name":"python"},{"id":19,"name":"java"},{"id":20,"name":"算法"},{"id":21,"name":"面试"},
      {"id":22,"name":"科技动态"},{"id":23,"name":"js"},{"id":24,"name":"设计"},{"id":25,"name":"数码产品"},
      {"id":26,"name":"软件测试"}
    ]
  },
  "message": "OK"
}

3. 切片模式

场景:当单个 store 比较大的时,可以采用一种 切片模式 进行模块拆分再组合

import {create} from 'zustand'
import {useEffect} from "react";

// 创建 counter 相关切片
const createCounterStore = (set) => {
  return {
    count: 0,
    inc: () => {
      return set(state => ({count: state.count + 1}))
    }
  }
}

const URL = 'http://geek.itheima.net/v1_0/channels'

// 创建 channel 相关切片
const createChannelStore = (set) => {
  return {
    channelList: [],
    fetchChannelList: async () => {
      const res = await fetch(URL)
      const jsonData = await res.json()
      set({channelList: jsonData.data.channels})
    }
  }
}

// 组合切片
const useStore = create((...a) => {
  return {
    ...createCounterStore(...a),
    ...createChannelStore(...a)
  }
})

function App() {
  const {count, inc, channelList, fetchChannelList} = useStore()

  useEffect(() => {
    fetchChannelList()
  }, [fetchChannelList])

  return (
      <>
        <button onClick={inc}>{count}</button>
        <ul>
          {channelList.map((item) => (
              <li key={item.id}>{item.name}</li>
          ))}
        </ul>
      </>
  )
}

export default App




 











 













 
 







 















4. 对接DevTools

# 简单的调试,安装 simple-zustand-devtools 的调试工具
npm i simple-zustand-devtools -D

1. 配置调试工具

import create from 'zustand'

// 导入核心方法
import { mountStoreDevtool } from 'simple-zustand-devtools'

// 省略部分代码...


// 开发环境开启调试
if (process.env.NODE_ENV === 'development') {
  mountStoreDevtool('channelStore', useChannelStore)
}


export default useChannelStore

2. 打开React调试工具

QXRrQVoydnkzNlJodXFna2o4TUxsdmowTk44RnhubGZNVVhwZ1cwPQ==