【问题标题】:React HotReload CodeChanges made in MobX Store在 MobX 商店中做出的 React 热重载代码更改
【发布时间】:2021-05-07 13:02:06
【问题描述】:

我总是必须重新启动开发服务器才能显示我在 mobx 存储类中所做的更改,例如将值记录到控制台中,这对开发人员来说并不友好。我愿意接受任何在更改Store.ts 代码时可能影响hot-reload 行为的解决方案。这是我对 nextJs 的实现。

_app.tsx

import { StoreProvider } from 'components/configurator/StoreProvider';

function App({ Component, pageProps }: AppProps) {
    return (
        <StoreProvider {...pageProps}>
            <Component {...pageProps} />
        </StoreProvider>
    );
}

export default App;

StoreProvider.tsx

import { createContext, useContext } from 'react';
import { CartStore } from 'shared/store';

let store;
export const StoreContext = createContext<CartStore>({} as CartStore);

export function useStore() {
    const context = useContext(StoreContext);
    if (context === undefined) {
        throw new Error('useStore must be used within StoreProvider');
    }

    return context;
}

export function StoreProvider({ children, initialState: initialData }) {
    const store = initializeStore(initialData);

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

function initializeStore(initialData = null) {
    const _store = store ?? new CartStore();

    // If your page has Next.js data fetching methods that use a Mobx store, it will
    // get hydrated here, check `pages/ssg.js` and `pages/ssr.js` for more details
    if (initialData) {
        _store.hydrate(initialData);
    }

    // For SSG and SSR always create a new store
    if (typeof window === 'undefined') return _store;

    // Create the store once in the client
    if (!store) store = _store;

    return _store;
}

Store.ts

import { makeAutoObservable } from 'mobx';
import { enableStaticRendering } from 'mobx-react-lite';
import { ProductGroupData } from './APITypes';

// NextJS specific, don´t render server-side
enableStaticRendering(typeof window === 'undefined');

export interface ProductGroup extends ProductGroupData {}

export class CartStore {
    productGroups: ProductGroup[] = [];

    constructor() {
        makeAutoObservable(this);
    }

    hydrate = (data) => {
        if (!data) return;

        this.productGroups = data.productGroups;
    };

    updateProductGroups = (productGroup: ProductGroup) => {
        const packageAlreadyInStore = this.productGroups.find((x) => x.name === productGroup.name);

        if (!packageAlreadyInStore) {
            this.productGroups.push(productGroup);
        } else {
            this.productGroups = this.productGroups.filter((x) => x.name !== productGroup.name);
        }
    };
}

【问题讨论】:

    标签: reactjs webpack next.js mobx


    【解决方案1】:

    我自己想通了,现在我通过从 pageProps 传递 _app.tsx 中的 StoreProvder 来补充水分。

    _app.tsx

    import 'styles/global.css';
    
    import type { AppProps } from 'next/app';
    
    import { StoreProvider } from 'components/configurator/StoreProvider';
    
    function App({ Component, pageProps }: AppProps) {
        return (
            <StoreProvider {...pageProps} hydrationData={pageProps.hydrationData}>
                <Component {...pageProps} />
            </StoreProvider>
        );
    }
    
    export default App;
    
    

    StoreProvider.tsx

    import { createContext, useContext } from 'react';
    import { CartStore } from 'shared/Store';
    
    let store;
    export const StoreContext = createContext<CartStore>({} as CartStore);
    
    export function useStore() {
        const context = useContext(StoreContext);
        if (context === undefined) {
            throw new Error('useStore must be used within StoreProvider');
        }
    
        return context;
    }
    
    export function StoreProvider({ children, hydrationData: hydrationData }) {
        const store = initializeStore(hydrationData);
    
        return <StoreContext.Provider value={store}>{children}</StoreContext.Provider>;
    }
    
    function initializeStore(hydrationData = null) {
        const _store = store ?? new CartStore();
    
        // If your page has Next.js data fetching methods that use a Mobx store, it will
        // get hydrated here, check `pages/ssg.js` and `pages/ssr.js` for more details
        if (hydrationData) {
            _store.hydrate(hydrationData);
        }
    
        // For SSG and SSR always create a new store
        if (typeof window === 'undefined') return _store;
    
        // Create the store once in the client
        if (!store) store = _store;
    
        return _store;
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-20
      • 2018-06-11
      • 2022-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多