/* eslint-disable react/react-in-jsx-scope, react/jsx-no-undef */ /* global React ReactCache ReactDOM SchedulerTracing ScheduleTracing */ const apps = []; const pieces = React.version.split('.'); const major = pieces[0] === '0' ? parseInt(pieces[1], 10) : parseInt(pieces[0], 10); const minor = pieces[0] === '0' ? parseInt(pieces[2], 10) : parseInt(pieces[1], 10); // Convenience wrapper to organize API features in DevTools. function Feature({children, label, version}) { return (
{label} {version}
{children}
); } // Simplify interaction tracing for tests below. let trace = null; if (typeof SchedulerTracing !== 'undefined') { trace = SchedulerTracing.unstable_trace; } else if (typeof ScheduleTracing !== 'undefined') { trace = ScheduleTracing.unstable_trace; } else { trace = (_, __, callback) => callback(); } // https://github.com/facebook/react/blob/main/CHANGELOG.md switch (major) { case 16: switch (minor) { case 7: if (typeof React.useState === 'function') { // Hooks function Hooks() { const [count, setCount] = React.useState(0); const incrementCount = React.useCallback( () => setCount(count + 1), [count] ); return (
count: {count}{' '}
); } apps.push( ); } case 6: // memo function LabelComponent({label}) { return ; } const AnonymousMemoized = React.memo(({label}) => ( )); const Memoized = React.memo(LabelComponent); const CustomMemoized = React.memo(LabelComponent); CustomMemoized.displayName = 'MemoizedLabelFunction'; apps.push( ); // Suspense const loadResource = ([text, ms]) => { return new Promise((resolve, reject) => { setTimeout(() => { resolve(text); }, ms); }); }; const getResourceKey = ([text, ms]) => text; const Resource = ReactCache.unstable_createResource( loadResource, getResourceKey ); class Suspending extends React.Component { state = {useSuspense: false}; useSuspense = () => this.setState({useSuspense: true}); render() { if (this.state.useSuspense) { const text = Resource.read(['loaded', 2000]); return text; } else { return ; } } } apps.push( loading...}> ); // lazy const LazyWithDefaultProps = React.lazy( () => new Promise(resolve => { function FooWithDefaultProps(props) { return (

{props.greeting}, {props.name}

); } FooWithDefaultProps.defaultProps = { name: 'World', greeting: 'Bonjour', }; resolve({ default: FooWithDefaultProps, }); }) ); apps.push( loading...}> ); case 5: case 4: // unstable_Profiler class ProfilerChild extends React.Component { state = {count: 0}; incrementCount = () => this.setState(prevState => ({count: prevState.count + 1})); render() { return (
count: {this.state.count}{' '}
); } } const onRender = (...args) => {}; const Profiler = React.unstable_Profiler || React.Profiler; apps.push(
); case 3: // createContext() const LocaleContext = React.createContext(); LocaleContext.displayName = 'LocaleContext'; const ThemeContext = React.createContext(); apps.push( {theme =>
theme: {theme}
}
{locale =>
locale: {locale}
}
); // forwardRef() const AnonymousFunction = React.forwardRef((props, ref) => (
{props.children}
)); const NamedFunction = React.forwardRef(function named(props, ref) { return
{props.children}
; }); const CustomName = React.forwardRef((props, ref) => (
{props.children}
)); CustomName.displayName = 'CustomNameForwardRef'; apps.push( AnonymousFunction NamedFunction CustomName ); // StrictMode class StrictModeChild extends React.Component { render() { return 'StrictModeChild'; } } apps.push( ); // unstable_AsyncMode (later renamed to unstable_ConcurrentMode, then ConcurrentMode) const ConcurrentMode = React.ConcurrentMode || React.unstable_ConcurrentMode || React.unstable_AsyncMode; apps.push(
unstable_AsyncMode was added in 16.3, renamed to unstable_ConcurrentMode in 16.5, and then renamed to ConcurrentMode in 16.7
); case 2: // Fragment apps.push(
one
two
); case 1: case 0: default: break; } break; case 15: break; case 14: break; default: break; } function Even() { return (even); } // Simple stateful app shared by all React versions class SimpleApp extends React.Component { state = {count: 0}; incrementCount = () => { const updaterFn = prevState => ({count: prevState.count + 1}); trace('Updating count', performance.now(), () => this.setState(updaterFn)); }; render() { const {count} = this.state; return (
{count % 2 === 0 ? ( count: {count} ) : ( count: {count} )}{' '}
); } } apps.push( ); // This component, with the version prop, helps organize DevTools at a glance. function TopLevelWrapperForDevTools({version}) { let header =

React {version}

; if (version.includes('canary')) { const commitSha = version.match(/.+canary-(.+)/)[1]; header = (

React canary{' '} {commitSha}

); } else if (version.includes('alpha')) { header =

React next

; } return (
{header} {apps}
); } TopLevelWrapperForDevTools.displayName = 'React'; ReactDOM.render( , document.getElementById('root') );