🍍react版的pinia构建极简状态管理

1,726 阅读2分钟

之前一直写vue,在vue2里面有vue.observable, 在vue3里面有pinia, 用起来都是极简的, 今年转react感觉状态管理都不是很好用,有限配置起来一点都不方便。后面看了ahooks里面的源码,在useReactivehooks里面找到了灵感。就有了现在的react-pinia, 因为这个库是依赖react hooks的,所以只适合react函数组件使用。react-pinia实现了局部状态管理和全局状态管理。

源码就不放出来了,怕被吐槽,原理其实也很简单,有点vue的思想去驱动界面更新

安装

npm i react-pinia -S

全局状态使用

定义全局状态,为了方便我就写在一起了,大家可以分开写

export default {
  user: {
    username: '',
    password: '',
  },
  article: {
    loading: false,
    list: [],
  },
}

在入口引入状态定义, 全局挂载,类似redux

import { Provider } from 'react-pinia'
import store from '@/store'
export default () => {
  return (
    <Provider store={store}>
      <App />
    </Provider>
  )
}

在然后page页面使用的时候就直接调用createStore方法就可以了, createStore是如何知道user 或者 article被更新了呢?或者说当前页面只需要知道user的数据被改动了,这里createStore 传当前页面接收的模块状态变化,可以是数组或者字符串,也可以不传,不传就任何模块的数据改动都能接收到,为了性能建议至少传一个。

import { createStore } from 'react-pinia'

export default () => {
  const { user } = createStore('user')
  return (
    <section>
      <input
        value={user.username}
        onChange={(e) => {
          user.username = e.target.value
        }}
      />
      {user.username}
    </section>
  )
}

局部状态使用

在局部状态中使用就非常简单了,定义的语法有点像pinia, 所以这个库就叫react-pinia, 直接上代码, 这里为了简便就都写在一起了,在这个里面useStore在组件中使用也是一样的可以接收需要监听的数据,不传就是所有

import { defineStore } from 'react-pinia'

// 定义局部状态
const useStore = defineStore('count', {
  state: () => {
    return {
      count: 0,
    }
  },
  getters: {
    doubleCount: (state: Record<string, any>) => {
      return state.count * 2
    },
  },
  actions: {
    add() {
      this.count += 1
    },
  },
})

const Child = () => {
  const store = useStore('count')
  return <section>{store.count}</section>
}

const App = () => {
  const store = useStore()
  return (
    <section>
      <p>count: {store.count}</p>
      <p>doubleCount: {store.doubleCount}</p>
      <button onClick={store.add}>add</button>
      <Child />
    </section>
  )
}