mobx hook中的使用
阅读原文时间:2023年07月05日阅读:1
  1. class

    import { inject, observer } from "mobx-react";
    // 需要使用mobx-react提供的Provider 包裹,需要使用的值直接使用props传递
    import { Provider } from "mobx-react";
    <Provider {...store}>{children}</Provider>
    // inject把需要使用的值放到props里
    // 这里使用的observer来自mobx-react
    @inject('store')
    @observer
    class A extends React.Component {
        ...
        this.props.store.value
    }
  2. function

    import { createContext, useContext } from 'react';
    const store = {
        ...
    }
    // createContext接受一个参数,该参数是Ctx.Provider上的value的默认值,没有默认值就给null
    const Ctx = createContext(store);
    const {Provider ,Consumer} = Ctx;
    // useContext接受createContext创建的context对象
    // useContext返回Ctx.Provider上的value值
    const useStore = () => useContext(Ctx);
    // 使用的时候需要被Ctx.Provider包裹,把对象赋给value
    <Ctx.Provider value={store}>
    </Ctx.Provider>
    <Consumer>{value => ...}</Consumer>
    // function component 需要用mobx-react-lite里observer处理
    // class使用的mobx-react里的observer,这里是不同的
    import { observer } from "mobx-react-lite";
    const B: React.FC =e () => {
        // 可以直接解构拿值
        const store = useStore();
    }
    export observer(B);
  3. 项目中的运用class

    // apps\link\src\solutions\biz-form\page\menu-buttons\pur-order-generate\PurOrderGenerate.tsx
    import * as React from "react";
    
    import { BizFormPresenter } from '../presenter/BizFormPresenter';
    
    const context = React.createContext<BizFormPresenter>(null);
    
    export const PresenterProvider = context.Provider;
    // class 使用方法
    export const PresenterConsumer = context.Consumer;
    // function 使用方法
    export const useBizFormPresenter = () => React.useContext(context);
    
    @contextProvider(PresenterConsumer, 'presenter')
    @observer
    export class PurOrderGenerateBtn extends React.Component<{
      presenter?: BizFormPresenter;
      entityName: string;
    }> {
    
    }
    export function contextProvider<P1, P2, PassName extends string = 'passContextValue'>(ContextConsumer: React.ComponentType<React.ConsumerProps<P2>>, passPropName: PassName = "passContextValue") {
        return (ComponentClass: React.ComponentType<P1 & { [key in PassName]?: P2 }>) => {
            class WrappedComponent extends React.PureComponent<P1 & { [key in PassName]?: P2 } & { passContextValue?: P2 }> {
                render() {
                    return (
                        <ContextConsumer>
                            {
                                (value: P2) => {
                                const passProps: { [key in PassName]: P2 } = {
                                    [passPropName]: this.props[passPropName] || value
                                } as any;
    
                                return (
                                    &lt;ComponentClass {...this.props} {...passProps} /&gt;
                                );
                            }
                        }
                    &lt;/ContextConsumer&gt;
                );
            }
        };
    
        hoistNonReactStatics(WrappedComponent, ComponentClass);
        return WrappedComponent as any;
    }
    }
  4. 项目中的运用hook

    // apps\link\src\main\screens\purchase\pur-comparison\form\customizeRightButtons.tsx
    const context = React.createContext<BizFormPresenter>(null);
    
    const CustomizeRightButtons: React.FC<CustomizeRightButtonsPropsModel> = (props) => {
      const presenter = useBizFormPresenter();
    
      return (
        <>
        {presenter.api.getFrom().value}
        </>
      );
    };
    
    export default observer(CustomizeRightButtons);
  5. 不需要响应式

    //直接调用
    store.value
  6. useLocalObservable

    import { Observer, useLocalObservable } from "mobx-react-lite";
    
    export default function MobxCount() {
      // 可以用来代替 useState useCallBack
      const state = useLocalObservable(() => ({
        count: 10,
        increment() {
          state.count++;
        },
        decrement() {
          state.count--;
        },
      }));
    
      return (
        <div>
          <Observer>{() => <div>{state.count}</div>}</Observer>
          <button
            onClick={() => {
              state.decrement();
            }}
          >
            decrement
          </button>
          <button
            onClick={() => {
              state.increment();
            }}
          >
            increment
          </button>
        </div>
      );
    }