|
| 1 | +# Mixed React Versions and Compatibility levels |
| 2 | + |
| 3 | +This example demos the ability to load two separate versions of react (v16.6.3 and v18.2.0). |
| 4 | + |
| 5 | +> Check the javascript version of this example [here](../different-react-versions/README.md). |
| 6 | +
|
| 7 | +Module Federation allows us to create an adapter which attaches a hooks-friendly version to render a section of thr app using modern versions. |
| 8 | + |
| 9 | +- `app1` uses and older version of react, not compatible with react Hooks |
| 10 | +- `app2` uses a modern react version and its components are hooks based |
| 11 | + |
| 12 | +## Running Demo |
| 13 | + |
| 14 | +Run `yarn start`. This will build and serve both `app1` and `app2` on ports 3001 and 3002 respectively. |
| 15 | + |
| 16 | +- [localhost:3001](http://localhost:3001/) (HOST) |
| 17 | +- [localhost:3002](http://localhost:3002/) (STANDALONE REMOTE) |
| 18 | + |
| 19 | +## How it works |
| 20 | + |
| 21 | +This example contains two important components, the `ReactAdapterConsumer` and `ReactAdapterProvider`. They are responsible to make the two versions of react work together. |
| 22 | + |
| 23 | +The adapter consumes both versions of react to "translate" the props into a fresh render. This could be presented as a HOC or federated components could have a legacy export containing the adapter build in. |
| 24 | + |
| 25 | +### [ReactAdapterProvider](./app2/src/components/ReactAdaperProvider.tsx) |
| 26 | + |
| 27 | +This component is responsible to dynamic render/hydrate the federated component using it host version of React. |
| 28 | + |
| 29 | +> You can see the usage [here](./app2/src/components/ModernReactComponent.tsx#29). |
| 30 | +
|
| 31 | +This is a generic component type, so you can pass the generic parameter to the component to specify the type of the props. |
| 32 | + |
| 33 | +```jsx |
| 34 | +import React from 'react'; |
| 35 | + |
| 36 | +export interface ButtonProps { |
| 37 | + color: 'red' | 'blue'; |
| 38 | +} |
| 39 | + |
| 40 | +const Button = (props: ButtonProps) => { |
| 41 | + return <button style={{ color: props.color }}>Click me</button>; |
| 42 | +}; |
| 43 | + |
| 44 | +export const Adapted = React.forwardRef< |
| 45 | + ReactAdaperProvider<ModernReactComponentProps>, |
| 46 | + ModernReactComponentProps |
| 47 | + >((props, ref) => { |
| 48 | + // the intellisesne will show the type of the props if you try to modify it |
| 49 | + return ( |
| 50 | + <ReactAdaperProvider<ButtonProps> component={Button} color="red" ref={ref} /> |
| 51 | + ); |
| 52 | +}); |
| 53 | +``` |
| 54 | + |
| 55 | +### [ReactAdapterConsumer](./app1/src/components/ReactAdapterConsumer.tsx) |
| 56 | + |
| 57 | +This component is responsible to render the federated component using the remote version of React. |
| 58 | + |
| 59 | +> You can see the usage [here](./app1/src/components/App.tsx#41). |
| 60 | +
|
| 61 | +This is a generic component type, so you can pass the generic parameter to the component to specify the type of the props. |
| 62 | + |
| 63 | +```jsx |
| 64 | +// remeber to add path alias to your tsconfig.base.json at the root of the workspace and the type definition file of the remote component |
| 65 | +// this demo contains an example that reproduce that but you can check in the gist below |
| 66 | +// https://gist.github.com/brunos3d/80235047c74b27573234c774ed474ef8 |
| 67 | +import type { ButtonProps } from 'app2/Button'; |
| 68 | + |
| 69 | +<ReactAdapterConsumer<ButtonProps> |
| 70 | + // you can try to modify the color value and the intellisense automatically will show the type of the props |
| 71 | + color="blue" |
| 72 | + fallback={<div>Loading...</div>} |
| 73 | + importer={() => import('app2/Button').then(module => ({ default: module.Adapted }))} |
| 74 | +/>; |
| 75 | +``` |
| 76 | + |
| 77 | +<img src="https://ssl.google-analytics.com/collect?v=1&t=event&ec=email&ea=open&t=event&tid=UA-120967034-1&z=1589682154&cid=ae045149-9d17-0367-bbb0-11c41d92b411&dt=ModuleFederationExamples&dp=/email/DifferentReactVersionsTypescript"> |
0 commit comments