react状态管理工具redux还是mobx?

一、redux

1. 工作原理: JavaScript 状态容器,提供可预测化的状态管理,严格遵守单向数据流

react状态管理工具redux还是mobx?_第1张图片

  • 首先使用store = createStore(reducer)创建项目唯一的一个全局状态中心store
  • 在组件中获取store的subscribe,getState,dispatch三个函数
  • 用户动作的action通过dispatch传递给sotre的reducer,根据用户要求修改store, 得到最新的store的快照state,然后触发组件中通过subscribe传递的回调函数,在回调函数中更新组件最新state,从而更新ui组件
2. 简单实现
function createStore(reducer) {
     

  let currentState; // 始终保持最新的state
  const listeners = []; // 用于存储订阅者

  // 订阅store
  function subscribe(fn) {
     
  	this.listeners.push(fn)
  }

  // 获取最新state
  function getState() {
     
  	return currentState
  }

  // 改变数据的唯一方法(约定)
  function dispatch(action) {
     
  	currentStatee = reducer(currentState,action)
  	this.listeners.forEach(item => item())
  }

  return {
      subscribe, getState, dispatch };
}

export default createStore;
3. 面试问题总结
3.1 为什么Redux总是要返回一个新的 state ?返回旧的 state 为什么不行 ?(为什么只能通过action来修改state,直接修改有什么问题?)

react状态管理工具redux还是mobx?_第2张图片

如果某个 Redux 的 reducer 直接修改并返回了传给它的 state 对象,那么根 state 对象的值的确会改变,但这个对象自身的引用没有变化。而Redux 决定是否要重新渲染包装的组件的hasChange,对建立在对根 state 对象进行浅比较,如果直接返回state,此它不会检测到 state 的变化,也就不会触发重新渲染。

3.3 为什么redux会设计3.2的形式呢?不直接设置比较真实的值是否改变呢?

因为在js中对一个对象所有的属性进行比较,唯一的方式是深比较,但是深比较十分耗费性能。需要比较的次数特别多,所以一个有效的解决方案就是做一个规定,当发生变化时,开发者都要返回一个新的对象,没有变化时,开发者返回旧的对象,这就是 redux 为什么要把 reducer 设计成纯函数的原因。

3.4 为什么reducer必须是纯函数?

纯函数的定义

 - 相同的输入永远返回相同的输出
 - 不修改函数的输入值
 - 不依赖外部环境状态
 - 无任何副作用 

reducer不能直接修改输入的state, 原因如同3.3

3.5 描述下react-redux的使用

主要为react组件提供redux的store的state,主要有两个api,Provider和connect,Provider用于在顶层把creatStore生成的store共享给所有react组件,在具体组件中使用connect获取该组件需要的store数据并定义相应的dispatch函数。

// redux定义的store中心
import {
      createStore } from 'redux'
const initState = {
     
    counter:0
}
const reducer = (state =initState, action: any) => {
     
    switch (action.type) {
     
        case 'add':
            return {
     ...state, counter:state.counter+1}
        case 'less':
            return {
     ...state, counter:state.counter-1}
        default:
            return {
     ...state}
    }
}
export const storeTest = createStore(reducer)

// 顶层提供store
import {
      Provider } from 'react-redux'
import {
      storeTest } from './store/test/index'
ReactDOM.render(
    <Provider store={
     storeTest}>
        <ConfigProvider locale={
     zhCN}>
            <App />
        </ConfigProvider>
    </Provider>,
    document.getElementById('root')
)


// react具体组件
import React from 'react' 
import {
      connect } from 'react-redux'
const TestComponent = (props:any) => {
     
    const [state,changeCounter] = props
    const handleClick = (type: string) => {
     
        changeCounter(type)
    }
   
    return (
        <div>
            <div onClick={
     () => handleClick('add')}>1</div>
            <div>{
     state.counter}</div>
            <div onClick={
     () => handleClick('less')}>1</div>
        </div>
    )
}
const mapStateToProps = (state:any) => {
     
    return {
     
      counter: state.counter
    }
}
const mapDispatchToProps = (dispatch:any) => {
     
    return {
     
        changeCounter: (type:string) => {
     
            dispatch({
     type: type, payload: 1})
        }
    }
}

const TestComponent2 = connect(
    mapStateToProps, 
    mapDispatchToProps
)(TestComponent)

export default TestComponent2

3.6 点击 button 后,需要先去服务端请求数据,只有等数据返回后,才能重新渲染 view,这种场景怎么实现?(怎么在action触发的时候增加日志功能)

redux借鉴了koa里面的中间件思想,使用中间件去增强dispatch
react状态管理工具redux还是mobx?_第3张图片

二、mobx

  1. 工作原理:Mobx基于观察者模式,采用多节点管理数据,是一个轻量级数据框架。
    react状态管理工具redux还是mobx?_第4张图片

三、比较?

  1. mobx中的state能本直接修改,多人协助使用的时候需要开启严格模式,再加上一套状态管理的规范;而reduxa遵循单一数据流/state只读/使用纯函数来执行修改state,保证了state的状态的可管理性,让出错的可能性和找问题的成本降到了最低。
  2. redux使用的复杂程度超过mobx; 实现相同的功能redux需要更多的代码

参考:
Redux 和 Mobx 哪个更适合你?
redux 和 mobX对比
redux和react-redux从实现到理解
Mobx React  最佳实践

你可能感兴趣的:(前端,react,redux,mobx)