mobx-react-lite -- react hooks 函数组件轻量级状态管理

1,770 阅读2分钟

最近一次新项目开发,首次尝试使用了mobx-react-lite + react hooks + typescript, 为什么这么搭配呢? 「「首先状态管理可以选择redux 和 mobx,redux在之前很多项目使用了,但是每次搭建都觉得很麻烦,然后看了些mobx,真心觉得上手快。」」 (废话)

传统React使用的数据管理库为Redux。Redux要解决的问题是统一数据流,数据流完全可控并可追踪。要实现该目标,便需要进行相关的约束。Redux由此引出了dispatch action reducer等概念,对state的概念进行强约束。然而对于一些项目来说,太过强,便失去了灵活性。Mobx便是来填补此空缺的。

这里对Redux和Mobx进行简单的对比:

  1. Redux的编程范式是函数式的而Mobx是面向对象的;
  2. 因此数据上来说Redux理想的是immutable的,每次都返回一个新的数据,而Mobx从始至终都是一份引用。因此Redux是支持数据回溯的;
  3. 然而和Redux相比,使用Mobx的组件可以做到精确更新,这一点得益于Mobx的observable;对应的,Redux是用dispath进行广播,通过Provider和connect来比对前后差别控制更新粒度,有时需要自己写SCU;Mobx更加精细一点。

Mobx核心概念 Mobx的核心原理是通过action触发state的变化,进而触发state的衍生对象(computed value & Reactions)。

项目搭建开始:
参考create react app -- adding typescript 搭建项目,链接:create-react-app.dev/docs/adding… (这块建议参考官网) 1, npx create-react-app my-app --template typescript
2, 添加 typescript
yarn add typescript @types/node @types/react @types/react-dom @types/jest

安装mobx-react-lite
yarn add mobx mobx-react mobx-react-lite --save

在src下新建store文件夹,然后新建index.tsx 和 counterStore.tsx,添加关于counter store counterStore.tsx:

import { useLocalObservable } from "mobx-react-lite";
export const initialValues = {    value: 0,};
type IpropInit = {
    value: number
};
export interface CounterProps extends IpropInit {
    increment: () => void;
    decrement: () => void;
}
const GlobalData = () => {
    const store = useLocalObservable<CounterProps>(() => ({
        /*observables*/        ...initialValues,
        increment() {
            store.value += 1;
        },
        decrement() {
            store.value -= 1;
        },
    }));
    return store;
};
export default GlobalData;

store/index.tsx:

import React, { createContext, FC } from "react";
import useCounterContext, { CounterProps } from "./counterStore";
export interface RootStoreSchema {
    counterStore: CounterProps;
}
// @ts-ignore
// @TODO 这个地方如果去掉@ts-ignore ,编译会报错,暂时没想到解决方案
// 评论里大家可以多多讨论
export const RootStoreContext = createContext<RootStoreSchema>(null);
const RootStore: FC = ({ children }) => {
    const counterContext = useCounterContext();
    return (
        <RootStoreContext.Provider
            value={{
                counterStore: counterContext
            }}
        >
            {children}
        </RootStoreContext.Provider>
    );};
export default RootStore;

然后创建一个counter组件
src/Counter.tsx

import React, { FC, useContext } from "react";
import { observer } from 'mobx-react-lite';
import { RootStoreContext } from './store/index';
interface IProps {};
const Counter:FC<IProps> = (props) => {
    const store = useContext(RootStoreContext);
    return <div>
        <div>{store.counterStore.value}</div>
        <button onClick={ () => store.counterStore.increment() }>increment</button>
        <button onClick={ () => store.counterStore.decrement() }>decrement</button>
    </div>};
export default observer(Counter);

App.tsx 里引入Counter

import React, { FC } from "react";
import RootStore from "./store/index";
import Counter from "./Counter"interface IProps {};
const App:FC<IProps> = (props) => {
  return (<RootStore>
    <Counter /></RootStore>
)};
export default App;

好了,大功告成:

参考:blog.csdn.net/weixin\_443…