React Hot Reload 代码更改在 MobX 商店中进行
React HotReload CodeChanges made in MobX Store
我总是需要重新启动开发服务器以显示我在我的 mobx 商店 class 中所做的更改,例如将值记录到控制台中,这对开发人员来说并不友好。在更改 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);
}
};
}
我自己想出来了,现在我通过 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;
}
我总是需要重新启动开发服务器以显示我在我的 mobx 商店 class 中所做的更改,例如将值记录到控制台中,这对开发人员来说并不友好。在更改 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);
}
};
}
我自己想出来了,现在我通过 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;
}