mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Upgrade compiler playground to use the newest nextjs release, which includes react compiler transform pipeline optimizations https://github.com/vercel/next.js/pull/75676/. Also made a drive-by fix to avoid the error `Cannot update a component ('Router') while rendering a different component ('StoreProvider'). To locate the bad setState() call inside 'StoreProvider', follow the stack trace as described in https://react.dev/link/setstate-in-render`. The bad setState came from `history.replaceState({}, '', \`#${hash}\`);`. Prior to this, playground ran side effects in a reducer (i.e. during render). These have now been moved an effect.
78 lines
1.8 KiB
TypeScript
78 lines
1.8 KiB
TypeScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
import type {Dispatch, ReactNode} from 'react';
|
|
import {useEffect, useReducer} from 'react';
|
|
import createContext from '../lib/createContext';
|
|
import {emptyStore} from '../lib/defaultStore';
|
|
import {saveStore, type Store} from '../lib/stores';
|
|
|
|
const StoreContext = createContext<Store>();
|
|
|
|
/**
|
|
* Hook to access the store.
|
|
*/
|
|
export const useStore = StoreContext.useContext;
|
|
|
|
const StoreDispatchContext = createContext<Dispatch<ReducerAction>>();
|
|
|
|
/**
|
|
* Hook to access the store dispatch function.
|
|
*/
|
|
export const useStoreDispatch = StoreDispatchContext.useContext;
|
|
|
|
/**
|
|
* Make Store and dispatch function available to all sub-components in children.
|
|
*/
|
|
export function StoreProvider({children}: {children: ReactNode}): JSX.Element {
|
|
const [store, dispatch] = useReducer(storeReducer, emptyStore);
|
|
useEffect(() => {
|
|
if (store !== emptyStore) {
|
|
saveStore(store);
|
|
}
|
|
}, [store]);
|
|
|
|
return (
|
|
<StoreContext.Provider value={store}>
|
|
<StoreDispatchContext.Provider value={dispatch}>
|
|
{children}
|
|
</StoreDispatchContext.Provider>
|
|
</StoreContext.Provider>
|
|
);
|
|
}
|
|
|
|
type ReducerAction =
|
|
| {
|
|
type: 'setStore';
|
|
payload: {
|
|
store: Store;
|
|
};
|
|
}
|
|
| {
|
|
type: 'updateFile';
|
|
payload: {
|
|
source: string;
|
|
};
|
|
};
|
|
|
|
function storeReducer(store: Store, action: ReducerAction): Store {
|
|
switch (action.type) {
|
|
case 'setStore': {
|
|
const newStore = action.payload.store;
|
|
return newStore;
|
|
}
|
|
case 'updateFile': {
|
|
const {source} = action.payload;
|
|
const newStore = {
|
|
...store,
|
|
source,
|
|
};
|
|
return newStore;
|
|
}
|
|
}
|
|
}
|