fixtures/devtools/regression/shared.js JAVASCRIPT 329 lines View on github.com → Search inside
1/* eslint-disable react/react-in-jsx-scope, react/jsx-no-undef */2/* global React ReactCache ReactDOM SchedulerTracing ScheduleTracing  */34const apps = [];56const pieces = React.version.split('.');7const major =8  pieces[0] === '0' ? parseInt(pieces[1], 10) : parseInt(pieces[0], 10);9const minor =10  pieces[0] === '0' ? parseInt(pieces[2], 10) : parseInt(pieces[1], 10);1112// Convenience wrapper to organize API features in DevTools.13function Feature({children, label, version}) {14  return (15    <div className="Feature">16      <div className="FeatureHeader">17        <code className="FeatureCode">{label}</code>18        <small>{version}</small>19      </div>20      {children}21    </div>22  );23}2425// Simplify interaction tracing for tests below.26let trace = null;27if (typeof SchedulerTracing !== 'undefined') {28  trace = SchedulerTracing.unstable_trace;29} else if (typeof ScheduleTracing !== 'undefined') {30  trace = ScheduleTracing.unstable_trace;31} else {32  trace = (_, __, callback) => callback();33}3435// https://github.com/facebook/react/blob/main/CHANGELOG.md36switch (major) {37  case 16:38    switch (minor) {39      case 7:40        if (typeof React.useState === 'function') {41          // Hooks42          function Hooks() {43            const [count, setCount] = React.useState(0);44            const incrementCount = React.useCallback(45              () => setCount(count + 1),46              [count]47            );48            return (49              <div>50                count: {count}{' '}51                <button onClick={incrementCount}>increment</button>52              </div>53            );54          }55          apps.push(56            <Feature key="Hooks" label="Hooks" version="16.7+">57              <Hooks />58            </Feature>59          );60        }61      case 6:62        // memo63        function LabelComponent({label}) {64          return <label>{label}</label>;65        }66        const AnonymousMemoized = React.memo(({label}) => (67          <label>{label}</label>68        ));69        const Memoized = React.memo(LabelComponent);70        const CustomMemoized = React.memo(LabelComponent);71        CustomMemoized.displayName = 'MemoizedLabelFunction';72        apps.push(73          <Feature key="memo" label="memo" version="16.6+">74            <AnonymousMemoized label="AnonymousMemoized" />75            <Memoized label="Memoized" />76            <CustomMemoized label="CustomMemoized" />77          </Feature>78        );7980        // Suspense81        const loadResource = ([text, ms]) => {82          return new Promise((resolve, reject) => {83            setTimeout(() => {84              resolve(text);85            }, ms);86          });87        };88        const getResourceKey = ([text, ms]) => text;89        const Resource = ReactCache.unstable_createResource(90          loadResource,91          getResourceKey92        );93        class Suspending extends React.Component {94          state = {useSuspense: false};95          useSuspense = () => this.setState({useSuspense: true});96          render() {97            if (this.state.useSuspense) {98              const text = Resource.read(['loaded', 2000]);99              return text;100            } else {101              return <button onClick={this.useSuspense}>load data</button>;102            }103          }104        }105        apps.push(106          <Feature key="Suspense" label="Suspense" version="16.6+">107            <React.Suspense fallback={<div>loading...</div>}>108              <Suspending />109            </React.Suspense>110          </Feature>111        );112113        // lazy114        const LazyWithDefaultProps = React.lazy(115          () =>116            new Promise(resolve => {117              function FooWithDefaultProps(props) {118                return (119                  <h1>120                    {props.greeting}, {props.name}121                  </h1>122                );123              }124              FooWithDefaultProps.defaultProps = {125                name: 'World',126                greeting: 'Bonjour',127              };128              resolve({129                default: FooWithDefaultProps,130              });131            })132        );133        apps.push(134          <Feature key="lazy" label="lazy" version="16.6+">135            <React.Suspense fallback={<div>loading...</div>}>136              <LazyWithDefaultProps greeting="Hello" />137            </React.Suspense>138          </Feature>139        );140      case 5:141      case 4:142        // unstable_Profiler143        class ProfilerChild extends React.Component {144          state = {count: 0};145          incrementCount = () =>146            this.setState(prevState => ({count: prevState.count + 1}));147          render() {148            return (149              <div>150                count: {this.state.count}{' '}151                <button onClick={this.incrementCount}>increment</button>152              </div>153            );154          }155        }156        const onRender = (...args) => {};157        const Profiler = React.unstable_Profiler || React.Profiler;158        apps.push(159          <Feature160            key="unstable_Profiler"161            label="unstable_Profiler"162            version="16.4+">163            <Profiler id="count" onRender={onRender}>164              <div>165                <ProfilerChild />166              </div>167            </Profiler>168          </Feature>169        );170      case 3:171        // createContext()172        const LocaleContext = React.createContext();173        LocaleContext.displayName = 'LocaleContext';174        const ThemeContext = React.createContext();175        apps.push(176          <Feature key="createContext" label="createContext" version="16.3+">177            <ThemeContext.Provider value="blue">178              <ThemeContext.Consumer>179                {theme => <div>theme: {theme}</div>}180              </ThemeContext.Consumer>181            </ThemeContext.Provider>182            <LocaleContext.Provider value="en-US">183              <LocaleContext.Consumer>184                {locale => <div>locale: {locale}</div>}185              </LocaleContext.Consumer>186            </LocaleContext.Provider>187          </Feature>188        );189190        // forwardRef()191        const AnonymousFunction = React.forwardRef((props, ref) => (192          <div ref={ref}>{props.children}</div>193        ));194        const NamedFunction = React.forwardRef(function named(props, ref) {195          return <div ref={ref}>{props.children}</div>;196        });197        const CustomName = React.forwardRef((props, ref) => (198          <div ref={ref}>{props.children}</div>199        ));200        CustomName.displayName = 'CustomNameForwardRef';201        apps.push(202          <Feature key="forwardRef" label="forwardRef" version="16.3+">203            <AnonymousFunction>AnonymousFunction</AnonymousFunction>204            <NamedFunction>NamedFunction</NamedFunction>205            <CustomName>CustomName</CustomName>206          </Feature>207        );208209        // StrictMode210        class StrictModeChild extends React.Component {211          render() {212            return 'StrictModeChild';213          }214        }215        apps.push(216          <Feature key="StrictMode" label="StrictMode" version="16.3+">217            <React.StrictMode>218              <StrictModeChild />219            </React.StrictMode>220          </Feature>221        );222223        // unstable_AsyncMode (later renamed to unstable_ConcurrentMode, then ConcurrentMode)224        const ConcurrentMode =225          React.ConcurrentMode ||226          React.unstable_ConcurrentMode ||227          React.unstable_AsyncMode;228        apps.push(229          <Feature230            key="AsyncMode/ConcurrentMode"231            label="AsyncMode/ConcurrentMode"232            version="16.3+">233            <ConcurrentMode>234              <div>235                unstable_AsyncMode was added in 16.3, renamed to236                unstable_ConcurrentMode in 16.5, and then renamed to237                ConcurrentMode in 16.7238              </div>239            </ConcurrentMode>240          </Feature>241        );242      case 2:243        // Fragment244        apps.push(245          <Feature key="Fragment" label="Fragment" version="16.4+">246            <React.Fragment>247              <div>one</div>248              <div>two</div>249            </React.Fragment>250          </Feature>251        );252      case 1:253      case 0:254      default:255        break;256    }257    break;258  case 15:259    break;260  case 14:261    break;262  default:263    break;264}265266function Even() {267  return <small>(even)</small>;268}269270// Simple stateful app shared by all React versions271class SimpleApp extends React.Component {272  state = {count: 0};273  incrementCount = () => {274    const updaterFn = prevState => ({count: prevState.count + 1});275    trace('Updating count', performance.now(), () => this.setState(updaterFn));276  };277  render() {278    const {count} = this.state;279    return (280      <div>281        {count % 2 === 0 ? (282          <span>283            count: {count} <Even />284          </span>285        ) : (286          <span>count: {count}</span>287        )}{' '}288        <button onClick={this.incrementCount}>increment</button>289      </div>290    );291  }292}293apps.push(294  <Feature key="Simple stateful app" label="Simple stateful app" version="any">295    <SimpleApp />296  </Feature>297);298299// This component, with the version prop, helps organize DevTools at a glance.300function TopLevelWrapperForDevTools({version}) {301  let header = <h1>React {version}</h1>;302  if (version.includes('canary')) {303    const commitSha = version.match(/.+canary-(.+)/)[1];304    header = (305      <h1>306        React canary{' '}307        <a href={`https://github.com/facebook/react/commit/${commitSha}`}>308          {commitSha}309        </a>310      </h1>311    );312  } else if (version.includes('alpha')) {313    header = <h1>React next</h1>;314  }315316  return (317    <div>318      {header}319      {apps}320    </div>321  );322}323TopLevelWrapperForDevTools.displayName = 'React';324325ReactDOM.render(326  <TopLevelWrapperForDevTools version={React.version} />,327  document.getElementById('root')328);

Findings

✓ No findings reported for this file.

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.