从hr口中了解react的状态管理库(mobx, recoil), 立马过来学习之mobx

简介: 从hr口中了解react的状态管理库(mobx, recoil), 立马过来学习之mobx

了解完Recoil后,立刻来学习了mobx,趁热打铁。


如果想要在react中使用mobx,我们需要安装mobx-react或者mobx-react-lite


  • 如果只想在函数式组件中使用mobx,那么只需要安装mobx, mobx-react-lite


  • 如果想要在类组件或者函数式组件中使用mobx,那么需要安装mobx, mobx-react


mobx


MobX 帮助你以一种简单直观的方式来完成工作,并且mobx中的每一个store都只能被初始化一次


网络异常,图片无法展示
|


mobx初体验


// store.js
    import { makeObservable, action, observable, computed } from 'mobx'
    class Num {
      constructor() {
        makeObservable(this, {
          // 让其成为可响应式的属性
          num: observable,
          // action: 表示指定该方法是一个action方法,不让控制台报警告
          // bound: 表示自动绑定该方法的this
          up: action.bound,
          down: action.bound,
          // computed: 表示当前值是一个计算值。会存在缓存
          double: computed
        })
      }
      num = 0
      up() {
        this.num++
      }
      down() {
        this.num--
      }
      get double() {
        return this.num * 2
      }
    }
    export default new Num()


// 使用store的值
    import React from 'react'
    import { observer } from 'mobx-react'
    import Num from '../store/index'
    function Test() {
      return (
        <div className="App">
          <p>{Num.num}</p>
          <p>{Num.double}</p>
          <button onClick={Num.up}>增加</button>
          <button onClick={Num.down}>减少</button>
        </div>
      )
    }
    export default observer(Test)


mobx的一些概念


State(状态)


状态 是驱动应用的数据。 就是我们通过mobx管理的数据。


Derivations(衍生)


任何 源自状态并且不会再有任何进一步的相互作用的东西就是衍生。


MobX 区分了两种类型的衍生:


  • Computed values(计算值)。它们是永远可以使用纯函数(pure function)从当前可观察状态中衍生出的值。感觉他特别像vuex中的getter。


  • Reactions(反应)。Reactions 是当状态改变时需要自动发生的副作用。需要有一个桥梁来连接命令式编程(imperative programming)和响应式编程(reactive programming)。或者说得更明确一些,它们最终都需要实现I / O 操作。


如果你想创建一个基于当前状态的值时,请使用 computed


Actions(动作)


动作 是任一一段可以改变状态的代码。用户事件、后端数据推送、预定事件、等等。 就是更新mobx管理的state。


mobx常见api讲解


observer


如果我们想在组件中使用mobx定义的state等,我们就需要使用observer将组件包裹。

注意这个高阶函数是在react-mobx库中的。


export default observer(Test)


makeObservable


定义store中属性和动作的配置。


makeObservable(this, {
      // 让其成为可响应式的属性
      num: observable,
      // action: 表示指定该方法是一个action方法
      // bound: 表示自动绑定该方法的this
      up: action.bound,
      down: action.bound,
      // computed: 表示当前值是一个计算值。会存在缓存
      double: computed
    })
  }


observable


让store中的数据成为可响应式的属性。


action


表示指定该方法是一个action方法。


bound


表示自动绑定该方法的this。省去我们在使用时给该方法绑定this。


computed


表示当前值是一个计算值。会将值进行缓存。当依赖的state发生变化后,自动计算,并重新缓存。


makeAutoObservable


我们知道,在定义完state或者action以后,我们需要配置他们,让其成为一个可响应式的数据或者一个action,这就很麻烦了。


但是这个api可以自动推断我们的state和action,并自动进行配置。


  • 所有的属性都成为observable


  • 所有的方法都成为action


  • 所有的gey都成为computed。 并且可以通过后续的参数来排除一些默认的这个配置。


// 第二个参数表示不适用他的默认推导,所以点击减号就会报错
// 第三个参数表示自动绑定this
 makeAutoObservable(this, { down: false }, { autoBind: true })


监听属性


autorun


自动收集使用的依赖,然后进行监听。


默认页面加载就会执行一次,当使用的state依赖发生变化,可以执行。类似于vue中的watchEffect。


autorun(() => {
  console.log('自动收集依赖,然后执行...', num1.num)
})


网络异常,图片无法展示
|


reaction


不会立刻执行,当监听的依赖变化时才会执行。类似于vue中的watch。


reaction(
      () => num1.num,
      () => {
        console.log('指定依赖,然后监听执行...', num1.num)
      }
    )


网络异常,图片无法展示
|


mobx处理异步更新


异步操作在mobx中不需要任何特殊处理,因为不论是何时引发的所有reactions都将自动更新。


异步直接操作action方法不会有问题,数据一样会被响应。但是控制台会报警告。


// 异步操作
  increment() {
    setTimeout(() => {
      this.num++
    })
  }


网络异常,图片无法展示
|


上面这个警告可以通过配置给其关闭。


configure({
      enforceActions: 'never'
    })


以上这种方式不推荐。不要直接在action函数中异步修改state。


正确解决异步操作


  • 通过定义一个额外的函数来充当中介,调用action函数。


// 正确的异步:方式一
  incrementAsync() {
    setTimeout(this.up, 1000)
  }


  • 通过runInAction来异步更改state。


// 正确的异步,方式二
  incrementAsync() {
    setTimeout(() => {
      runInAction(() => {
        this.num++
      })
    }, 1000)
  }


对于多个store,如何优雅的使用


我们在一个组件中可能会使用多个store中的state。所以,为了避免多次导入不同的文件,我们可以有以下处理方式


  • 定义一个统一的store出口文件,将store统一导出。


// store/index.js
    import a from './aStore.js'
    import b from './bStore.js'
    export {
        a, 
        b
    }


  • 通过react提供的context


import { createContext, useContext } from 'react'
    import a from './aStore.js'
    import b from './bStore.js'
    class RootStore {
      a = a
      b = b
    }
    const store = new RootStore()
    const context = createContext(store)
    export default function useStore() {
      return useContext(context)
    }


第一种方式是我们开发中常用的方法。


做一个异步小demo来测试


// person.js
    import axios from 'axios'
    import { makeAutoObservable, runInAction } from 'mobx'
    class Person {
      constructor() {
        makeAutoObservable(this, null, { autoBind: true })
      }
      person = {}
      getPersonInfo() {
        runInAction(async () => {
          const res = await axios('http://myjson.dit.upm.es/api/bins/irav')
          this.person = res.data
        })
      }
    }
    export default new Person()


// 组件使用
    import { observer } from 'mobx-react'
    import React from 'react'
    import person from '../store/test2'
    function Test2() {
      return (
        <div>
          <h1>展示个人信息</h1>
          <p>{person.person.name}</p>
          <p>{person.person.age}</p>
          <button onClick={person.getPersonInfo}>点击获取</button>
        </div>
      )
    }
    export default observer(Test2)


网络异常,图片无法展示
|


相关文章
|
2月前
|
前端开发 JavaScript UED
React 图标库使用指南
本文详细介绍如何在 React 项目中使用 `react-icons` 等图标库,涵盖环境搭建、基础使用、常见问题与易错点、高级用法等内容,并通过代码案例进行说明。适合初学者和进阶开发者参考。
110 8
|
3月前
|
前端开发 JavaScript API
React开发需要了解的10个库
本文首发于微信公众号“前端徐徐”,介绍了React及其常用库。React是由Meta开发的JavaScript库,用于构建动态用户界面,广泛应用于Facebook、Instagram等知名网站。文章详细讲解了Axios、Formik、React Helmet、React-Redux、React Router DOM、Dotenv、ESLint、Storybook、Framer Motion和React Bootstrap等库的使用方法和应用场景,帮助开发者提升开发效率和代码质量。
155 4
React开发需要了解的10个库
|
3月前
|
前端开发 JavaScript
React学习之——条件渲染
【10月更文挑战第16天】React 中没有像Vue中v-if这种指令。React 中的条件渲染和 JavaScript 中的一样,使用 JavaScript 运算符 if 或者条件运算符去创建元素来表现当前的状态,然后让 React 根据它们来更新 UI。
|
4月前
|
前端开发 JavaScript
学习react基础(3)_setState、state、jsx、使用ref的几种形式
本文探讨了React中this.setState和this.state的区别,以及React的核心概念,包括核心库的使用、JSX语法、类与函数组件的区别、事件处理和ref的使用。
93 3
学习react基础(3)_setState、state、jsx、使用ref的几种形式
|
4月前
|
前端开发
学习react基础(2)_props、state和style的使用
本文介绍了React中组件间数据传递的方式,包括props和state的使用,以及如何在React组件中使用style样式。
46 0
|
2月前
|
前端开发 JavaScript API
探究 React Hooks:如何利用全新 API 优化组件逻辑复用与状态管理
本文深入探讨React Hooks的使用方法,通过全新API优化组件逻辑复用和状态管理,提升开发效率和代码可维护性。
|
2月前
|
前端开发 JavaScript 安全
学习如何为 React 组件编写测试:
学习如何为 React 组件编写测试:
45 2
|
3月前
|
资源调度 前端开发 JavaScript
React进阶学习
React进阶学习
26 1
|
3月前
|
资源调度 前端开发 JavaScript
React中classnames库使用
【10月更文挑战第7天】
|
3月前
|
前端开发 JavaScript API
利用React Hooks简化状态管理
【10月更文挑战第1天】利用React Hooks简化状态管理