安装

  1. yarn add mobx
  2. yarn add mobx-react

为了能使用装饰器安装 @babel/plugin-proposal-decorators

  1. yarn add @babel/plugin-proposal-decorators

修改 webpack 配置

  1. yarn eject

在 package.json 中的 babel 属性中添加 plugins

  1. "babel": {
  2. "presets": [
  3. "react-app"
  4. ],
  5. "plugins": [
  6. ["@babel/plugin-proposal-decorators", {"legacy": true}]
  7. ]
  8. }

在 tsconfig.json 中添加 2 行配置, 参考

  1. "experimentalDecorators": true,
  2. "useDefineForClassFields": true

使用装饰器写法定义状态

  1. import { makeObservable, observable, action } from 'mobx'
  2. export class AuthStore {
  3. @observable isLogin = false
  4. @observable isLoading = false
  5. @observable values = {
  6. username: 'aaa',
  7. password: '',
  8. }
  9. constructor() {
  10. makeObservable(this)
  11. }
  12. @action setIsLoading(isLogin: boolean) {
  13. this.isLogin = isLogin
  14. }
  15. @action setUsername(username: string) {
  16. console.log(username)
  17. this.values.username = username
  18. }
  19. @action setPassword(password: string) {
  20. this.values.password = password
  21. }
  22. @action login() {
  23. console.log('登录中')
  24. this.isLoading = true
  25. setTimeout(() => {
  26. console.log('登录成功')
  27. this.isLogin = true
  28. this.isLoading = false
  29. }, 1000)
  30. }
  31. @action register() {
  32. console.log('注册中')
  33. this.isLoading = true
  34. setTimeout(() => {
  35. console.log('注册成功')
  36. this.isLoading = false
  37. }, 1000)
  38. }
  39. @action logout() {
  40. this.isLogin = false
  41. console.log('已注销')
  42. }
  43. }

定义 useStore 方法

  1. import { createContext, useContext } from 'react'
  2. import { AuthStore } from './auth'
  3. const context = createContext({
  4. AuthStore: new AuthStore(),
  5. })
  6. export const useStore = () => useContext(context)

在组件中使用全局状态

注意 inputRef 需要将类型声明为 MutableRefObject, 否则 TS 报错

  1. import { useStore } from '../store'
  2. import { observer } from 'mobx-react'
  3. import { MutableRefObject, useRef } from 'react'
  4. const Login = observer(() => {
  5. const { AuthStore } = useStore()
  6. const inputRef = useRef() as MutableRefObject<HTMLInputElement>
  7. const handleInput = () => {
  8. AuthStore.setUsername(inputRef.current.value)
  9. }
  10. return (
  11. <>
  12. <div>Login: {AuthStore.values.username}</div>
  13. <input type="text" onChange={handleInput} ref={inputRef} />
  14. </>
  15. )
  16. })
  17. export default Login