Mobx-React-lite学习

5,873 阅读2分钟

mobx-react-litemobx-react的轻量版,增加了对hooks的支持

是用来管理状态的工具

使用指南(1):

以下是利用mobx-react-lite + useContext

使用到:

  • mobx-react-lite的 useObserver
  • mobx 的 observable, action, computed, makeObservable
  • react 的 createContextuseContext

1. 创建store

// store.ts
import { observable, action, computed, makeObservable } from 'mobx';

export class CounterStore {
  constructor() {
    // 解决数据更新页面不跟着更新的方法
    makeObservable(this);
  }

  @observable
  count = 0;

  @action
  increase() {
    this.count = this.count + 1;
  }

  @action
  decrease() {
    this.count = this.count - 1;
  }

  @computed
  get doubleCount() {
    return this.count * 2;
  }
}

tips: 数据更新,试图不更新,就在store中加上它试一试

  constructor() {
    // 监听更新,(解决数据更新,页面不跟着更新的方法)
    makeObservable(this);
  }

2. 创建context

创建storeContext 并导出,这个后代组件在useContext时就可以拿到storeContext中每一个store的实例对象了。

// context.ts
import { createContext } from 'react';
import { CounterStore } from '.';

// 利用createContext 创建storeContext
export const storeContext = createContext({
  counterStore: new CounterStore(),
  // 当然可以new 多个store啦
  // aStore:new AStore() 
  // ....
});

3. 创建useStore

通过 useStores 获取 React.createContext 给的初始值对象(前提是没有使用 StoresContext.Provider 组件,如果使用了该组件,则拿到的是 StoresContext.Provider 的 value 属性对应的值)

// useStore.ts
import React, { useContext } from 'react';
import { storeContext } from './contexts';
export const useStore = () => useContext(storeContext);

4. 组件中使用

后代组件调用useStore拿到store的实例对象,这样就可以获取store中的数据并且调用store中的action 修改状态。

组件要用useObserver监听,然后会将状态更新到组件中。

// MobxDemo.tsx
import { useStore } from '../../store/useStore';
import Demo1 from './components/Demo1';
import { useObserver } from 'mobx-react-lite';

function MobxDemo() {
  const store = useStore();
  const { counterStore } = store;

  const handleIncrease = () => {
    counterStore.increase();
  };
  const handleDecrease = () => {
    counterStore.decrease();
  };
  return useObserver(() => (
    <div>
      <p>count:{counterStore.count}</p>
      <button onClick={handleIncrease}>add</button>
      <button onClick={handleDecrease}>minus</button>
      <p>doubleCount:{counterStore.doubleCount}</p>
      <Demo1 count={counterStore.count} />
    </div>
  ));
}

export default MobxDemo;

其实除了这种用法,mobx-react-lite还有一些别的Api:useLocalStore、observer等

使用指南(2):

  • 使用到 mobx-react-liteuseLocalStoreobserver
  • reactcreateContextuseContext

1. 创建store

// 状态库 store.ts
export const createStore = () => {
    const store = {
        cities : [
            '石家庄',
            '北京',
            '上海',
            '定州'
        ],
        
        get allCities() {
            return this.cities
        },
        addCity(city: string) {
             this.cities.push(city)
        }
    }
return store
}


export default createStore
export type TStore = ReturnType<typeof createStore>

2. 创建context

// context.ts
import { useLocalStore } from 'mobx-react-lite';
import { createContext } from 'react';
import createStore, { TStore } from './sotre';

export const CityContext = createContext<TStore | null>(null);

const StoreProvider = ({ children }: any) => {
  const store = useLocalStore(createStore);

  return <CityContext.Provider value={store}>{children}</CityContext.Provider>;
};

export default StoreProvider;

3. 使用

// App.tsx
import StoreProvider from './mobxStore/context';
import City from './City';
export default function App() {
  return (
    <StoreProvider>
      <div>
        <City />
      </div>
    </StoreProvider>
  );
}

4. 子组件使用

// City.tsx
import { useContext } from 'react';
import { observer } from 'mobx-react-lite';
import { CityContext } from './mobxStore/context';
function City() {
  const store = useContext(CityContext);
  const handleAddCity = () => {
    store?.addCity('广州');
  };
  return (
    <div>
      <p className="city">cities:{store?.allCities.join(',')}</p>
      <button onClick={handleAddCity}>添加city</button>
    </div>
  );
}
export default observer(City);