-
Notifications
You must be signed in to change notification settings - Fork 47k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
362 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
EXTEND_ESLINT=true | ||
SKIP_PREFLIGHT_CHECK=true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
src/*/node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
|
||
# testing | ||
/coverage | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
.env.local | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
|
||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# copies of shared | ||
src/*/shared | ||
src/*/node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
{ | ||
"name": "react-nesting-example", | ||
"version": "0.1.0", | ||
"private": true, | ||
"dependencies": { | ||
"react-scripts": "3.4.1" | ||
}, | ||
"scripts": { | ||
"postinstall": "run-p install:*", | ||
"install:legacy": "cd src/legacy && npm install", | ||
"install:modern": "cd src/modern && npm install", | ||
"copy:legacy": "cpx 'src/shared/**' 'src/legacy/shared/'", | ||
"copy:modern": "cpx 'src/shared/**' 'src/modern/shared/'", | ||
"watch:legacy": "cpx 'src/shared/**' 'src/legacy/shared/' --watch --no-initial", | ||
"watch:modern": "cpx 'src/shared/**' 'src/modern/shared/' --watch --no-initial", | ||
"prebuild": "run-p copy:*", | ||
"prestart": "run-p copy:*", | ||
"start": "run-p start-app watch:*", | ||
"start-app": "react-scripts start", | ||
"build": "react-scripts build", | ||
"eject": "react-scripts eject" | ||
}, | ||
"eslintConfig": { | ||
"extends": "react-app" | ||
}, | ||
"browserslist": { | ||
"production": [ | ||
">0.2%", | ||
"not dead", | ||
"not op_mini all" | ||
], | ||
"development": [ | ||
"last 1 chrome version", | ||
"last 1 firefox version", | ||
"last 1 safari version" | ||
] | ||
}, | ||
"devDependencies": { | ||
"cpx": "^1.5.0", | ||
"npm-run-all": "^4.1.5" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
<title>React App</title> | ||
</head> | ||
<body> | ||
<noscript>You need to enable JavaScript to run this app.</noscript> | ||
<div id="root"></div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
import './modern/index'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import React from 'react'; | ||
import {useContext} from 'react'; | ||
import {Link} from 'react-router-dom'; | ||
import ThemeContext from './shared/ThemeContext'; | ||
import Clock from './shared/Clock'; | ||
|
||
export default function AboutSection() { | ||
const theme = useContext(ThemeContext); | ||
return ( | ||
<div style={{border: '1px dashed black', padding: 20}}> | ||
<h3>src/legacy/Greeting.js</h3> | ||
<h4 style={{color: theme}}> | ||
This component is rendered by the nested React. | ||
</h4> | ||
<Clock /> | ||
<b> | ||
<Link to="/">Go to Home</Link> | ||
</b> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import React from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
import ThemeContext from './shared/ThemeContext'; | ||
import {__RouterContext} from 'react-router'; | ||
|
||
/* eslint-disable react/jsx-pascal-case */ | ||
|
||
function Bridge({children, context}) { | ||
return ( | ||
<ThemeContext.Provider value={context.theme}> | ||
<__RouterContext.Provider value={context.router}> | ||
{children} | ||
</__RouterContext.Provider> | ||
</ThemeContext.Provider> | ||
); | ||
} | ||
|
||
export default function createLegacyRoot(container) { | ||
return { | ||
render(Component, props, context) { | ||
ReactDOM.render( | ||
<Bridge context={context}> | ||
<Component {...props} /> | ||
</Bridge>, | ||
container | ||
); | ||
}, | ||
unmount() { | ||
ReactDOM.unmountComponentAtNode(container); | ||
}, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"private": true, | ||
"name": "react-nesting-example-legacy", | ||
"dependencies": { | ||
"react": "0.0.0-3d0895557", | ||
"react-dom": "0.0.0-3d0895557", | ||
"react-router-dom": "5.2.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import React from 'react'; | ||
import {useContext} from 'react'; | ||
|
||
import ThemeContext from './shared/ThemeContext'; | ||
import withLegacyRoot from './withLegacyRoot'; | ||
|
||
const Greeting = withLegacyRoot(() => import('../legacy/Greeting')); | ||
|
||
export default function AboutPage() { | ||
const theme = useContext(ThemeContext); | ||
return ( | ||
<> | ||
<h2>src/modern/AboutPage.js</h2> | ||
<h3 style={{color: theme}}> | ||
This component is rendered by the outer React. | ||
</h3> | ||
<Greeting /> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import React from 'react'; | ||
import {useState, Suspense} from 'react'; | ||
import {BrowserRouter, Switch, Route} from 'react-router-dom'; | ||
|
||
import HomePage from './HomePage'; | ||
import AboutPage from './AboutPage'; | ||
import ThemeContext from './shared/ThemeContext'; | ||
|
||
export default function App() { | ||
const [theme, setTheme] = useState('slategrey'); | ||
|
||
function handleToggleClick() { | ||
if (theme === 'slategrey') { | ||
setTheme('hotpink'); | ||
} else { | ||
setTheme('slategrey'); | ||
} | ||
} | ||
|
||
return ( | ||
<BrowserRouter> | ||
<ThemeContext.Provider value={theme}> | ||
<div style={{fontFamily: 'sans-serif'}}> | ||
<div | ||
style={{ | ||
margin: 20, | ||
padding: 20, | ||
border: '1px solid black', | ||
minHeight: 300, | ||
}}> | ||
<button onClick={handleToggleClick}>Toggle Theme Context</button> | ||
<br /> | ||
<Suspense fallback={<Spinner />}> | ||
<Switch> | ||
<Route path="/about"> | ||
<AboutPage /> | ||
</Route> | ||
<Route path="/"> | ||
<HomePage /> | ||
</Route> | ||
</Switch> | ||
</Suspense> | ||
</div> | ||
</div> | ||
</ThemeContext.Provider> | ||
</BrowserRouter> | ||
); | ||
} | ||
|
||
function Spinner() { | ||
return null; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import React from 'react'; | ||
import {useContext} from 'react'; | ||
import {Link} from 'react-router-dom'; | ||
|
||
import ThemeContext from './shared/ThemeContext'; | ||
import Clock from './shared/Clock'; | ||
|
||
export default function HomePage() { | ||
const theme = useContext(ThemeContext); | ||
return ( | ||
<> | ||
<h2>src/modern/HomePage.js</h2> | ||
<h3 style={{color: theme}}> | ||
This component is rendered by the outer React. | ||
</h3> | ||
<Clock /> | ||
<b> | ||
<Link to="/about">Go to About</Link> | ||
</b> | ||
</> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import React from 'react'; | ||
import ReactDOM from 'react-dom'; | ||
import App from './App'; | ||
|
||
ReactDOM.render(<App />, document.getElementById('root')); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"private": true, | ||
"name": "react-nesting-example-modern", | ||
"dependencies": { | ||
"react": "0.0.0-3d0895557", | ||
"react-dom": "0.0.0-3d0895557", | ||
"react-router-dom": "5.2.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import React from 'react'; | ||
import {useContext, useMemo, useRef, useState, useLayoutEffect} from 'react'; | ||
|
||
import {__RouterContext} from 'react-router'; | ||
import ThemeContext from './shared/ThemeContext'; | ||
|
||
let bridgeRecord = { | ||
status: 'pending', | ||
promise: null, | ||
result: null, | ||
}; | ||
|
||
export default function withLegacy(getLegacyComponent) { | ||
let componentRecord = { | ||
status: 'pending', | ||
promise: null, | ||
result: null, | ||
}; | ||
|
||
return function Wrapper(props) { | ||
const createLegacyRoot = readRecord(bridgeRecord, () => | ||
import('../legacy/createLegacyRoot') | ||
).default; | ||
const Component = readRecord(componentRecord, getLegacyComponent).default; | ||
const containerRef = useRef(null); | ||
const [root, setRoot] = useState(null); | ||
|
||
const theme = useContext(ThemeContext); | ||
const router = useContext(__RouterContext); | ||
const context = useMemo( | ||
() => ({ | ||
theme, | ||
router, | ||
}), | ||
[theme, router] | ||
); | ||
|
||
useLayoutEffect(() => { | ||
if (!root) { | ||
let r = createLegacyRoot(containerRef.current); | ||
setRoot(r); | ||
return () => r.unmount(); | ||
} | ||
}, [createLegacyRoot, root]); | ||
|
||
useLayoutEffect(() => { | ||
if (root) { | ||
root.render(Component, props, context); | ||
} | ||
}, [Component, root, props, context]); | ||
|
||
return <div style={{display: 'contents'}} ref={containerRef} />; | ||
}; | ||
} | ||
|
||
function readRecord(record, createPromise) { | ||
if (record.status === 'fulfilled') { | ||
return record.result; | ||
} | ||
if (record.status === 'rejected') { | ||
throw record.result; | ||
} | ||
if (!record.promise) { | ||
record.promise = createPromise().then( | ||
value => { | ||
if (record.status === 'pending') { | ||
record.status = 'fulfilled'; | ||
record.promise = null; | ||
record.result = value; | ||
} | ||
}, | ||
error => { | ||
if (record.status === 'pending') { | ||
record.status = 'rejected'; | ||
record.promise = null; | ||
record.result = error; | ||
} | ||
} | ||
); | ||
} | ||
throw record.promise; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import React from 'react'; | ||
|
||
import useTime from './useTime'; | ||
|
||
export default function Clock() { | ||
const time = useTime(); | ||
return <p>Time: {time}</p>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import {createContext} from 'react'; | ||
|
||
const ThemeContext = createContext(null); | ||
|
||
export default ThemeContext; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import {useState, useEffect} from 'react'; | ||
|
||
export default function useTimer() { | ||
const [value, setValue] = useState(() => new Date()); | ||
useEffect(() => { | ||
const id = setInterval(() => { | ||
setValue(new Date()); | ||
}, 1000); | ||
return () => clearInterval(id); | ||
}, []); | ||
return value.toLocaleTimeString(); | ||
} |