Best JavaScript code snippet using playwright-internal
ReactFiberHooks.new.js
Source:ReactFiberHooks.new.js  
...1485    mountState(id);1486    return id;1487  }1488}1489function updateOpaqueIdentifier()                      {1490  const id = updateState(undefined)[0];1491  return id;1492}1493function rerenderOpaqueIdentifier()                      {1494  const id = rerenderState(undefined)[0];1495  return id;1496}1497function dispatchAction      (1498  fiber       ,1499  queue                   ,1500  action   ,1501) {1502  if (__DEV__) {1503    if (typeof arguments[3] === 'function') {1504      console.error(1505        "State updates from the useState() and useReducer() Hooks don't support the " +1506          'second callback argument. To execute a side effect after ' +1507          'rendering, declare it in the component body with useEffect().',1508      );1509    }1510  }1511  const eventTime = requestEventTime();1512  const lane = requestUpdateLane(fiber);1513  const update               = {1514    lane,1515    action,1516    eagerReducer: null,1517    eagerState: null,1518    next: (null     ),1519  };1520  // Append the update to the end of the list.1521  const pending = queue.pending;1522  if (pending === null) {1523    // This is the first update. Create a circular list.1524    update.next = update;1525  } else {1526    update.next = pending.next;1527    pending.next = update;1528  }1529  queue.pending = update;1530  const alternate = fiber.alternate;1531  if (1532    fiber === currentlyRenderingFiber ||1533    (alternate !== null && alternate === currentlyRenderingFiber)1534  ) {1535    // This is a render phase update. Stash it in a lazily-created map of1536    // queue -> linked list of updates. After this render pass, we'll restart1537    // and apply the stashed updates on top of the work-in-progress hook.1538    didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true;1539  } else {1540    if (1541      fiber.lanes === NoLanes &&1542      (alternate === null || alternate.lanes === NoLanes)1543    ) {1544      // The queue is currently empty, which means we can eagerly compute the1545      // next state before entering the render phase. If the new state is the1546      // same as the current state, we may be able to bail out entirely.1547      const lastRenderedReducer = queue.lastRenderedReducer;1548      if (lastRenderedReducer !== null) {1549        let prevDispatcher;1550        if (__DEV__) {1551          prevDispatcher = ReactCurrentDispatcher.current;1552          ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;1553        }1554        try {1555          const currentState    = (queue.lastRenderedState     );1556          const eagerState = lastRenderedReducer(currentState, action);1557          // Stash the eagerly computed state, and the reducer used to compute1558          // it, on the update object. If the reducer hasn't changed by the1559          // time we enter the render phase, then the eager state can be used1560          // without calling the reducer again.1561          update.eagerReducer = lastRenderedReducer;1562          update.eagerState = eagerState;1563          if (is(eagerState, currentState)) {1564            // Fast path. We can bail out without scheduling React to re-render.1565            // It's still possible that we'll need to rebase this update later,1566            // if the component re-renders for a different reason and by that1567            // time the reducer has changed.1568            return;1569          }1570        } catch (error) {1571          // Suppress the error. It will throw again in the render phase.1572        } finally {1573          if (__DEV__) {1574            ReactCurrentDispatcher.current = prevDispatcher;1575          }1576        }1577      }1578    }1579    if (__DEV__) {1580      // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests1581      if (typeof jest !== 'undefined') {1582        warnIfNotScopedWithMatchingAct(fiber);1583        warnIfNotCurrentlyActingUpdatesInDev(fiber);1584      }1585    }1586    scheduleUpdateOnFiber(fiber, lane, eventTime);1587  }1588  if (__DEV__) {1589    if (enableDebugTracing) {1590      if (fiber.mode & DebugTracingMode) {1591        const name = getComponentName(fiber.type) || 'Unknown';1592        logStateUpdateScheduled(name, lane, action);1593      }1594    }1595  }1596  if (enableSchedulingProfiler) {1597    markStateUpdateScheduled(fiber, lane);1598  }1599}1600export const ContextOnlyDispatcher             = {1601  readContext,1602  useCallback: throwInvalidHookError,1603  useContext: throwInvalidHookError,1604  useEffect: throwInvalidHookError,1605  useImperativeHandle: throwInvalidHookError,1606  useLayoutEffect: throwInvalidHookError,1607  useMemo: throwInvalidHookError,1608  useReducer: throwInvalidHookError,1609  useRef: throwInvalidHookError,1610  useState: throwInvalidHookError,1611  useDebugValue: throwInvalidHookError,1612  useDeferredValue: throwInvalidHookError,1613  useTransition: throwInvalidHookError,1614  useMutableSource: throwInvalidHookError,1615  useOpaqueIdentifier: throwInvalidHookError,1616  unstable_isNewReconciler: enableNewReconciler,1617};1618const HooksDispatcherOnMount             = {1619  readContext,1620  useCallback: mountCallback,1621  useContext: readContext,1622  useEffect: mountEffect,1623  useImperativeHandle: mountImperativeHandle,1624  useLayoutEffect: mountLayoutEffect,1625  useMemo: mountMemo,1626  useReducer: mountReducer,1627  useRef: mountRef,1628  useState: mountState,1629  useDebugValue: mountDebugValue,1630  useDeferredValue: mountDeferredValue,1631  useTransition: mountTransition,1632  useMutableSource: mountMutableSource,1633  useOpaqueIdentifier: mountOpaqueIdentifier,1634  unstable_isNewReconciler: enableNewReconciler,1635};1636const HooksDispatcherOnUpdate             = {1637  readContext,1638  useCallback: updateCallback,1639  useContext: readContext,1640  useEffect: updateEffect,1641  useImperativeHandle: updateImperativeHandle,1642  useLayoutEffect: updateLayoutEffect,1643  useMemo: updateMemo,1644  useReducer: updateReducer,1645  useRef: updateRef,1646  useState: updateState,1647  useDebugValue: updateDebugValue,1648  useDeferredValue: updateDeferredValue,1649  useTransition: updateTransition,1650  useMutableSource: updateMutableSource,1651  useOpaqueIdentifier: updateOpaqueIdentifier,1652  unstable_isNewReconciler: enableNewReconciler,1653};1654const HooksDispatcherOnRerender             = {1655  readContext,1656  useCallback: updateCallback,1657  useContext: readContext,1658  useEffect: updateEffect,1659  useImperativeHandle: updateImperativeHandle,1660  useLayoutEffect: updateLayoutEffect,1661  useMemo: updateMemo,1662  useReducer: rerenderReducer,1663  useRef: updateRef,1664  useState: rerenderState,1665  useDebugValue: updateDebugValue,1666  useDeferredValue: rerenderDeferredValue,1667  useTransition: rerenderTransition,1668  useMutableSource: updateMutableSource,1669  useOpaqueIdentifier: rerenderOpaqueIdentifier,1670  unstable_isNewReconciler: enableNewReconciler,1671};1672let HooksDispatcherOnMountInDEV                    = null;1673let HooksDispatcherOnMountWithHookTypesInDEV                    = null;1674let HooksDispatcherOnUpdateInDEV                    = null;1675let HooksDispatcherOnRerenderInDEV                    = null;1676let InvalidNestedHooksDispatcherOnMountInDEV                    = null;1677let InvalidNestedHooksDispatcherOnUpdateInDEV                    = null;1678let InvalidNestedHooksDispatcherOnRerenderInDEV                    = null;1679if (__DEV__) {1680  const warnInvalidContextAccess = () => {1681    console.error(1682      'Context can only be read while React is rendering. ' +1683        'In classes, you can read it in the render method or getDerivedStateFromProps. ' +1684        'In function components, you can read it directly in the function body, but not ' +1685        'inside Hooks like useReducer() or useMemo().',1686    );1687  };1688  const warnInvalidHookAccess = () => {1689    console.error(1690      'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' +1691        'You can only call Hooks at the top level of your React function. ' +1692        'For more information, see ' +1693        'https://reactjs.org/link/rules-of-hooks',1694    );1695  };1696  HooksDispatcherOnMountInDEV = {1697    readContext   (1698      context                 ,1699      observedBits                         ,1700    )    {1701      return readContext(context, observedBits);1702    },1703    useCallback   (callback   , deps                            )    {1704      currentHookNameInDev = 'useCallback';1705      mountHookTypesDev();1706      checkDepsAreArrayDev(deps);1707      return mountCallback(callback, deps);1708    },1709    useContext   (1710      context                 ,1711      observedBits                         ,1712    )    {1713      currentHookNameInDev = 'useContext';1714      mountHookTypesDev();1715      return readContext(context, observedBits);1716    },1717    useEffect(1718      create                           ,1719      deps                            ,1720    )       {1721      currentHookNameInDev = 'useEffect';1722      mountHookTypesDev();1723      checkDepsAreArrayDev(deps);1724      return mountEffect(create, deps);1725    },1726    useImperativeHandle   (1727      ref                                                                   ,1728      create         ,1729      deps                            ,1730    )       {1731      currentHookNameInDev = 'useImperativeHandle';1732      mountHookTypesDev();1733      checkDepsAreArrayDev(deps);1734      return mountImperativeHandle(ref, create, deps);1735    },1736    useLayoutEffect(1737      create                           ,1738      deps                            ,1739    )       {1740      currentHookNameInDev = 'useLayoutEffect';1741      mountHookTypesDev();1742      checkDepsAreArrayDev(deps);1743      return mountLayoutEffect(create, deps);1744    },1745    useMemo   (create         , deps                            )    {1746      currentHookNameInDev = 'useMemo';1747      mountHookTypesDev();1748      checkDepsAreArrayDev(deps);1749      const prevDispatcher = ReactCurrentDispatcher.current;1750      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1751      try {1752        return mountMemo(create, deps);1753      } finally {1754        ReactCurrentDispatcher.current = prevDispatcher;1755      }1756    },1757    useReducer         (1758      reducer             ,1759      initialArg   ,1760      init         ,1761    )                   {1762      currentHookNameInDev = 'useReducer';1763      mountHookTypesDev();1764      const prevDispatcher = ReactCurrentDispatcher.current;1765      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1766      try {1767        return mountReducer(reducer, initialArg, init);1768      } finally {1769        ReactCurrentDispatcher.current = prevDispatcher;1770      }1771    },1772    useRef   (initialValue   )                 {1773      currentHookNameInDev = 'useRef';1774      mountHookTypesDev();1775      return mountRef(initialValue);1776    },1777    useState   (1778      initialState               ,1779    )                                     {1780      currentHookNameInDev = 'useState';1781      mountHookTypesDev();1782      const prevDispatcher = ReactCurrentDispatcher.current;1783      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1784      try {1785        return mountState(initialState);1786      } finally {1787        ReactCurrentDispatcher.current = prevDispatcher;1788      }1789    },1790    useDebugValue   (value   , formatterFn                      )       {1791      currentHookNameInDev = 'useDebugValue';1792      mountHookTypesDev();1793      return mountDebugValue(value, formatterFn);1794    },1795    useDeferredValue   (value   )    {1796      currentHookNameInDev = 'useDeferredValue';1797      mountHookTypesDev();1798      return mountDeferredValue(value);1799    },1800    useTransition()                                  {1801      currentHookNameInDev = 'useTransition';1802      mountHookTypesDev();1803      return mountTransition();1804    },1805    useMutableSource                  (1806      source                       ,1807      getSnapshot                                              ,1808      subscribe                                            ,1809    )           {1810      currentHookNameInDev = 'useMutableSource';1811      mountHookTypesDev();1812      return mountMutableSource(source, getSnapshot, subscribe);1813    },1814    useOpaqueIdentifier()                      {1815      currentHookNameInDev = 'useOpaqueIdentifier';1816      mountHookTypesDev();1817      return mountOpaqueIdentifier();1818    },1819    unstable_isNewReconciler: enableNewReconciler,1820  };1821  HooksDispatcherOnMountWithHookTypesInDEV = {1822    readContext   (1823      context                 ,1824      observedBits                         ,1825    )    {1826      return readContext(context, observedBits);1827    },1828    useCallback   (callback   , deps                            )    {1829      currentHookNameInDev = 'useCallback';1830      updateHookTypesDev();1831      return mountCallback(callback, deps);1832    },1833    useContext   (1834      context                 ,1835      observedBits                         ,1836    )    {1837      currentHookNameInDev = 'useContext';1838      updateHookTypesDev();1839      return readContext(context, observedBits);1840    },1841    useEffect(1842      create                           ,1843      deps                            ,1844    )       {1845      currentHookNameInDev = 'useEffect';1846      updateHookTypesDev();1847      return mountEffect(create, deps);1848    },1849    useImperativeHandle   (1850      ref                                                                   ,1851      create         ,1852      deps                            ,1853    )       {1854      currentHookNameInDev = 'useImperativeHandle';1855      updateHookTypesDev();1856      return mountImperativeHandle(ref, create, deps);1857    },1858    useLayoutEffect(1859      create                           ,1860      deps                            ,1861    )       {1862      currentHookNameInDev = 'useLayoutEffect';1863      updateHookTypesDev();1864      return mountLayoutEffect(create, deps);1865    },1866    useMemo   (create         , deps                            )    {1867      currentHookNameInDev = 'useMemo';1868      updateHookTypesDev();1869      const prevDispatcher = ReactCurrentDispatcher.current;1870      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1871      try {1872        return mountMemo(create, deps);1873      } finally {1874        ReactCurrentDispatcher.current = prevDispatcher;1875      }1876    },1877    useReducer         (1878      reducer             ,1879      initialArg   ,1880      init         ,1881    )                   {1882      currentHookNameInDev = 'useReducer';1883      updateHookTypesDev();1884      const prevDispatcher = ReactCurrentDispatcher.current;1885      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1886      try {1887        return mountReducer(reducer, initialArg, init);1888      } finally {1889        ReactCurrentDispatcher.current = prevDispatcher;1890      }1891    },1892    useRef   (initialValue   )                 {1893      currentHookNameInDev = 'useRef';1894      updateHookTypesDev();1895      return mountRef(initialValue);1896    },1897    useState   (1898      initialState               ,1899    )                                     {1900      currentHookNameInDev = 'useState';1901      updateHookTypesDev();1902      const prevDispatcher = ReactCurrentDispatcher.current;1903      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1904      try {1905        return mountState(initialState);1906      } finally {1907        ReactCurrentDispatcher.current = prevDispatcher;1908      }1909    },1910    useDebugValue   (value   , formatterFn                      )       {1911      currentHookNameInDev = 'useDebugValue';1912      updateHookTypesDev();1913      return mountDebugValue(value, formatterFn);1914    },1915    useDeferredValue   (value   )    {1916      currentHookNameInDev = 'useDeferredValue';1917      updateHookTypesDev();1918      return mountDeferredValue(value);1919    },1920    useTransition()                                  {1921      currentHookNameInDev = 'useTransition';1922      updateHookTypesDev();1923      return mountTransition();1924    },1925    useMutableSource                  (1926      source                       ,1927      getSnapshot                                              ,1928      subscribe                                            ,1929    )           {1930      currentHookNameInDev = 'useMutableSource';1931      updateHookTypesDev();1932      return mountMutableSource(source, getSnapshot, subscribe);1933    },1934    useOpaqueIdentifier()                      {1935      currentHookNameInDev = 'useOpaqueIdentifier';1936      updateHookTypesDev();1937      return mountOpaqueIdentifier();1938    },1939    unstable_isNewReconciler: enableNewReconciler,1940  };1941  HooksDispatcherOnUpdateInDEV = {1942    readContext   (1943      context                 ,1944      observedBits                         ,1945    )    {1946      return readContext(context, observedBits);1947    },1948    useCallback   (callback   , deps                            )    {1949      currentHookNameInDev = 'useCallback';1950      updateHookTypesDev();1951      return updateCallback(callback, deps);1952    },1953    useContext   (1954      context                 ,1955      observedBits                         ,1956    )    {1957      currentHookNameInDev = 'useContext';1958      updateHookTypesDev();1959      return readContext(context, observedBits);1960    },1961    useEffect(1962      create                           ,1963      deps                            ,1964    )       {1965      currentHookNameInDev = 'useEffect';1966      updateHookTypesDev();1967      return updateEffect(create, deps);1968    },1969    useImperativeHandle   (1970      ref                                                                   ,1971      create         ,1972      deps                            ,1973    )       {1974      currentHookNameInDev = 'useImperativeHandle';1975      updateHookTypesDev();1976      return updateImperativeHandle(ref, create, deps);1977    },1978    useLayoutEffect(1979      create                           ,1980      deps                            ,1981    )       {1982      currentHookNameInDev = 'useLayoutEffect';1983      updateHookTypesDev();1984      return updateLayoutEffect(create, deps);1985    },1986    useMemo   (create         , deps                            )    {1987      currentHookNameInDev = 'useMemo';1988      updateHookTypesDev();1989      const prevDispatcher = ReactCurrentDispatcher.current;1990      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;1991      try {1992        return updateMemo(create, deps);1993      } finally {1994        ReactCurrentDispatcher.current = prevDispatcher;1995      }1996    },1997    useReducer         (1998      reducer             ,1999      initialArg   ,2000      init         ,2001    )                   {2002      currentHookNameInDev = 'useReducer';2003      updateHookTypesDev();2004      const prevDispatcher = ReactCurrentDispatcher.current;2005      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;2006      try {2007        return updateReducer(reducer, initialArg, init);2008      } finally {2009        ReactCurrentDispatcher.current = prevDispatcher;2010      }2011    },2012    useRef   (initialValue   )                 {2013      currentHookNameInDev = 'useRef';2014      updateHookTypesDev();2015      return updateRef(initialValue);2016    },2017    useState   (2018      initialState               ,2019    )                                     {2020      currentHookNameInDev = 'useState';2021      updateHookTypesDev();2022      const prevDispatcher = ReactCurrentDispatcher.current;2023      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;2024      try {2025        return updateState(initialState);2026      } finally {2027        ReactCurrentDispatcher.current = prevDispatcher;2028      }2029    },2030    useDebugValue   (value   , formatterFn                      )       {2031      currentHookNameInDev = 'useDebugValue';2032      updateHookTypesDev();2033      return updateDebugValue(value, formatterFn);2034    },2035    useDeferredValue   (value   )    {2036      currentHookNameInDev = 'useDeferredValue';2037      updateHookTypesDev();2038      return updateDeferredValue(value);2039    },2040    useTransition()                                  {2041      currentHookNameInDev = 'useTransition';2042      updateHookTypesDev();2043      return updateTransition();2044    },2045    useMutableSource                  (2046      source                       ,2047      getSnapshot                                              ,2048      subscribe                                            ,2049    )           {2050      currentHookNameInDev = 'useMutableSource';2051      updateHookTypesDev();2052      return updateMutableSource(source, getSnapshot, subscribe);2053    },2054    useOpaqueIdentifier()                      {2055      currentHookNameInDev = 'useOpaqueIdentifier';2056      updateHookTypesDev();2057      return updateOpaqueIdentifier();2058    },2059    unstable_isNewReconciler: enableNewReconciler,2060  };2061  HooksDispatcherOnRerenderInDEV = {2062    readContext   (2063      context                 ,2064      observedBits                         ,2065    )    {2066      return readContext(context, observedBits);2067    },2068    useCallback   (callback   , deps                            )    {2069      currentHookNameInDev = 'useCallback';2070      updateHookTypesDev();2071      return updateCallback(callback, deps);2072    },2073    useContext   (2074      context                 ,2075      observedBits                         ,2076    )    {2077      currentHookNameInDev = 'useContext';2078      updateHookTypesDev();2079      return readContext(context, observedBits);2080    },2081    useEffect(2082      create                           ,2083      deps                            ,2084    )       {2085      currentHookNameInDev = 'useEffect';2086      updateHookTypesDev();2087      return updateEffect(create, deps);2088    },2089    useImperativeHandle   (2090      ref                                                                   ,2091      create         ,2092      deps                            ,2093    )       {2094      currentHookNameInDev = 'useImperativeHandle';2095      updateHookTypesDev();2096      return updateImperativeHandle(ref, create, deps);2097    },2098    useLayoutEffect(2099      create                           ,2100      deps                            ,2101    )       {2102      currentHookNameInDev = 'useLayoutEffect';2103      updateHookTypesDev();2104      return updateLayoutEffect(create, deps);2105    },2106    useMemo   (create         , deps                            )    {2107      currentHookNameInDev = 'useMemo';2108      updateHookTypesDev();2109      const prevDispatcher = ReactCurrentDispatcher.current;2110      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;2111      try {2112        return updateMemo(create, deps);2113      } finally {2114        ReactCurrentDispatcher.current = prevDispatcher;2115      }2116    },2117    useReducer         (2118      reducer             ,2119      initialArg   ,2120      init         ,2121    )                   {2122      currentHookNameInDev = 'useReducer';2123      updateHookTypesDev();2124      const prevDispatcher = ReactCurrentDispatcher.current;2125      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;2126      try {2127        return rerenderReducer(reducer, initialArg, init);2128      } finally {2129        ReactCurrentDispatcher.current = prevDispatcher;2130      }2131    },2132    useRef   (initialValue   )                 {2133      currentHookNameInDev = 'useRef';2134      updateHookTypesDev();2135      return updateRef(initialValue);2136    },2137    useState   (2138      initialState               ,2139    )                                     {2140      currentHookNameInDev = 'useState';2141      updateHookTypesDev();2142      const prevDispatcher = ReactCurrentDispatcher.current;2143      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;2144      try {2145        return rerenderState(initialState);2146      } finally {2147        ReactCurrentDispatcher.current = prevDispatcher;2148      }2149    },2150    useDebugValue   (value   , formatterFn                      )       {2151      currentHookNameInDev = 'useDebugValue';2152      updateHookTypesDev();2153      return updateDebugValue(value, formatterFn);2154    },2155    useDeferredValue   (value   )    {2156      currentHookNameInDev = 'useDeferredValue';2157      updateHookTypesDev();2158      return rerenderDeferredValue(value);2159    },2160    useTransition()                                  {2161      currentHookNameInDev = 'useTransition';2162      updateHookTypesDev();2163      return rerenderTransition();2164    },2165    useMutableSource                  (2166      source                       ,2167      getSnapshot                                              ,2168      subscribe                                            ,2169    )           {2170      currentHookNameInDev = 'useMutableSource';2171      updateHookTypesDev();2172      return updateMutableSource(source, getSnapshot, subscribe);2173    },2174    useOpaqueIdentifier()                      {2175      currentHookNameInDev = 'useOpaqueIdentifier';2176      updateHookTypesDev();2177      return rerenderOpaqueIdentifier();2178    },2179    unstable_isNewReconciler: enableNewReconciler,2180  };2181  InvalidNestedHooksDispatcherOnMountInDEV = {2182    readContext   (2183      context                 ,2184      observedBits                         ,2185    )    {2186      warnInvalidContextAccess();2187      return readContext(context, observedBits);2188    },2189    useCallback   (callback   , deps                            )    {2190      currentHookNameInDev = 'useCallback';2191      warnInvalidHookAccess();2192      mountHookTypesDev();2193      return mountCallback(callback, deps);2194    },2195    useContext   (2196      context                 ,2197      observedBits                         ,2198    )    {2199      currentHookNameInDev = 'useContext';2200      warnInvalidHookAccess();2201      mountHookTypesDev();2202      return readContext(context, observedBits);2203    },2204    useEffect(2205      create                           ,2206      deps                            ,2207    )       {2208      currentHookNameInDev = 'useEffect';2209      warnInvalidHookAccess();2210      mountHookTypesDev();2211      return mountEffect(create, deps);2212    },2213    useImperativeHandle   (2214      ref                                                                   ,2215      create         ,2216      deps                            ,2217    )       {2218      currentHookNameInDev = 'useImperativeHandle';2219      warnInvalidHookAccess();2220      mountHookTypesDev();2221      return mountImperativeHandle(ref, create, deps);2222    },2223    useLayoutEffect(2224      create                           ,2225      deps                            ,2226    )       {2227      currentHookNameInDev = 'useLayoutEffect';2228      warnInvalidHookAccess();2229      mountHookTypesDev();2230      return mountLayoutEffect(create, deps);2231    },2232    useMemo   (create         , deps                            )    {2233      currentHookNameInDev = 'useMemo';2234      warnInvalidHookAccess();2235      mountHookTypesDev();2236      const prevDispatcher = ReactCurrentDispatcher.current;2237      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;2238      try {2239        return mountMemo(create, deps);2240      } finally {2241        ReactCurrentDispatcher.current = prevDispatcher;2242      }2243    },2244    useReducer         (2245      reducer             ,2246      initialArg   ,2247      init         ,2248    )                   {2249      currentHookNameInDev = 'useReducer';2250      warnInvalidHookAccess();2251      mountHookTypesDev();2252      const prevDispatcher = ReactCurrentDispatcher.current;2253      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;2254      try {2255        return mountReducer(reducer, initialArg, init);2256      } finally {2257        ReactCurrentDispatcher.current = prevDispatcher;2258      }2259    },2260    useRef   (initialValue   )                 {2261      currentHookNameInDev = 'useRef';2262      warnInvalidHookAccess();2263      mountHookTypesDev();2264      return mountRef(initialValue);2265    },2266    useState   (2267      initialState               ,2268    )                                     {2269      currentHookNameInDev = 'useState';2270      warnInvalidHookAccess();2271      mountHookTypesDev();2272      const prevDispatcher = ReactCurrentDispatcher.current;2273      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;2274      try {2275        return mountState(initialState);2276      } finally {2277        ReactCurrentDispatcher.current = prevDispatcher;2278      }2279    },2280    useDebugValue   (value   , formatterFn                      )       {2281      currentHookNameInDev = 'useDebugValue';2282      warnInvalidHookAccess();2283      mountHookTypesDev();2284      return mountDebugValue(value, formatterFn);2285    },2286    useDeferredValue   (value   )    {2287      currentHookNameInDev = 'useDeferredValue';2288      warnInvalidHookAccess();2289      mountHookTypesDev();2290      return mountDeferredValue(value);2291    },2292    useTransition()                                  {2293      currentHookNameInDev = 'useTransition';2294      warnInvalidHookAccess();2295      mountHookTypesDev();2296      return mountTransition();2297    },2298    useMutableSource                  (2299      source                       ,2300      getSnapshot                                              ,2301      subscribe                                            ,2302    )           {2303      currentHookNameInDev = 'useMutableSource';2304      warnInvalidHookAccess();2305      mountHookTypesDev();2306      return mountMutableSource(source, getSnapshot, subscribe);2307    },2308    useOpaqueIdentifier()                      {2309      currentHookNameInDev = 'useOpaqueIdentifier';2310      warnInvalidHookAccess();2311      mountHookTypesDev();2312      return mountOpaqueIdentifier();2313    },2314    unstable_isNewReconciler: enableNewReconciler,2315  };2316  InvalidNestedHooksDispatcherOnUpdateInDEV = {2317    readContext   (2318      context                 ,2319      observedBits                         ,2320    )    {2321      warnInvalidContextAccess();2322      return readContext(context, observedBits);2323    },2324    useCallback   (callback   , deps                            )    {2325      currentHookNameInDev = 'useCallback';2326      warnInvalidHookAccess();2327      updateHookTypesDev();2328      return updateCallback(callback, deps);2329    },2330    useContext   (2331      context                 ,2332      observedBits                         ,2333    )    {2334      currentHookNameInDev = 'useContext';2335      warnInvalidHookAccess();2336      updateHookTypesDev();2337      return readContext(context, observedBits);2338    },2339    useEffect(2340      create                           ,2341      deps                            ,2342    )       {2343      currentHookNameInDev = 'useEffect';2344      warnInvalidHookAccess();2345      updateHookTypesDev();2346      return updateEffect(create, deps);2347    },2348    useImperativeHandle   (2349      ref                                                                   ,2350      create         ,2351      deps                            ,2352    )       {2353      currentHookNameInDev = 'useImperativeHandle';2354      warnInvalidHookAccess();2355      updateHookTypesDev();2356      return updateImperativeHandle(ref, create, deps);2357    },2358    useLayoutEffect(2359      create                           ,2360      deps                            ,2361    )       {2362      currentHookNameInDev = 'useLayoutEffect';2363      warnInvalidHookAccess();2364      updateHookTypesDev();2365      return updateLayoutEffect(create, deps);2366    },2367    useMemo   (create         , deps                            )    {2368      currentHookNameInDev = 'useMemo';2369      warnInvalidHookAccess();2370      updateHookTypesDev();2371      const prevDispatcher = ReactCurrentDispatcher.current;2372      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;2373      try {2374        return updateMemo(create, deps);2375      } finally {2376        ReactCurrentDispatcher.current = prevDispatcher;2377      }2378    },2379    useReducer         (2380      reducer             ,2381      initialArg   ,2382      init         ,2383    )                   {2384      currentHookNameInDev = 'useReducer';2385      warnInvalidHookAccess();2386      updateHookTypesDev();2387      const prevDispatcher = ReactCurrentDispatcher.current;2388      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;2389      try {2390        return updateReducer(reducer, initialArg, init);2391      } finally {2392        ReactCurrentDispatcher.current = prevDispatcher;2393      }2394    },2395    useRef   (initialValue   )                 {2396      currentHookNameInDev = 'useRef';2397      warnInvalidHookAccess();2398      updateHookTypesDev();2399      return updateRef(initialValue);2400    },2401    useState   (2402      initialState               ,2403    )                                     {2404      currentHookNameInDev = 'useState';2405      warnInvalidHookAccess();2406      updateHookTypesDev();2407      const prevDispatcher = ReactCurrentDispatcher.current;2408      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;2409      try {2410        return updateState(initialState);2411      } finally {2412        ReactCurrentDispatcher.current = prevDispatcher;2413      }2414    },2415    useDebugValue   (value   , formatterFn                      )       {2416      currentHookNameInDev = 'useDebugValue';2417      warnInvalidHookAccess();2418      updateHookTypesDev();2419      return updateDebugValue(value, formatterFn);2420    },2421    useDeferredValue   (value   )    {2422      currentHookNameInDev = 'useDeferredValue';2423      warnInvalidHookAccess();2424      updateHookTypesDev();2425      return updateDeferredValue(value);2426    },2427    useTransition()                                  {2428      currentHookNameInDev = 'useTransition';2429      warnInvalidHookAccess();2430      updateHookTypesDev();2431      return updateTransition();2432    },2433    useMutableSource                  (2434      source                       ,2435      getSnapshot                                              ,2436      subscribe                                            ,2437    )           {2438      currentHookNameInDev = 'useMutableSource';2439      warnInvalidHookAccess();2440      updateHookTypesDev();2441      return updateMutableSource(source, getSnapshot, subscribe);2442    },2443    useOpaqueIdentifier()                      {2444      currentHookNameInDev = 'useOpaqueIdentifier';2445      warnInvalidHookAccess();2446      updateHookTypesDev();2447      return updateOpaqueIdentifier();2448    },2449    unstable_isNewReconciler: enableNewReconciler,2450  };2451  InvalidNestedHooksDispatcherOnRerenderInDEV = {2452    readContext   (2453      context                 ,2454      observedBits                         ,2455    )    {2456      warnInvalidContextAccess();2457      return readContext(context, observedBits);2458    },2459    useCallback   (callback   , deps                            )    {2460      currentHookNameInDev = 'useCallback';2461      warnInvalidHookAccess();...ReactFiberHooks.old.js
Source:ReactFiberHooks.old.js  
...1445    mountState(id);1446    return id;1447  }1448}1449function updateOpaqueIdentifier()                      {1450  const id = updateState(undefined)[0];1451  return id;1452}1453function rerenderOpaqueIdentifier()                      {1454  const id = rerenderState(undefined)[0];1455  return id;1456}1457function dispatchAction      (1458  fiber       ,1459  queue                   ,1460  action   ,1461) {1462  if (__DEV__) {1463    if (typeof arguments[3] === 'function') {1464      console.error(1465        "State updates from the useState() and useReducer() Hooks don't support the " +1466          'second callback argument. To execute a side effect after ' +1467          'rendering, declare it in the component body with useEffect().',1468      );1469    }1470  }1471  const eventTime = requestEventTime();1472  const lane = requestUpdateLane(fiber);1473  const update               = {1474    lane,1475    action,1476    eagerReducer: null,1477    eagerState: null,1478    next: (null     ),1479  };1480  // Append the update to the end of the list.1481  const pending = queue.pending;1482  if (pending === null) {1483    // This is the first update. Create a circular list.1484    update.next = update;1485  } else {1486    update.next = pending.next;1487    pending.next = update;1488  }1489  queue.pending = update;1490  const alternate = fiber.alternate;1491  if (1492    fiber === currentlyRenderingFiber ||1493    (alternate !== null && alternate === currentlyRenderingFiber)1494  ) {1495    // This is a render phase update. Stash it in a lazily-created map of1496    // queue -> linked list of updates. After this render pass, we'll restart1497    // and apply the stashed updates on top of the work-in-progress hook.1498    didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true;1499  } else {1500    if (1501      fiber.lanes === NoLanes &&1502      (alternate === null || alternate.lanes === NoLanes)1503    ) {1504      // The queue is currently empty, which means we can eagerly compute the1505      // next state before entering the render phase. If the new state is the1506      // same as the current state, we may be able to bail out entirely.1507      const lastRenderedReducer = queue.lastRenderedReducer;1508      if (lastRenderedReducer !== null) {1509        let prevDispatcher;1510        if (__DEV__) {1511          prevDispatcher = ReactCurrentDispatcher.current;1512          ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;1513        }1514        try {1515          const currentState    = (queue.lastRenderedState     );1516          const eagerState = lastRenderedReducer(currentState, action);1517          // Stash the eagerly computed state, and the reducer used to compute1518          // it, on the update object. If the reducer hasn't changed by the1519          // time we enter the render phase, then the eager state can be used1520          // without calling the reducer again.1521          update.eagerReducer = lastRenderedReducer;1522          update.eagerState = eagerState;1523          if (is(eagerState, currentState)) {1524            // Fast path. We can bail out without scheduling React to re-render.1525            // It's still possible that we'll need to rebase this update later,1526            // if the component re-renders for a different reason and by that1527            // time the reducer has changed.1528            return;1529          }1530        } catch (error) {1531          // Suppress the error. It will throw again in the render phase.1532        } finally {1533          if (__DEV__) {1534            ReactCurrentDispatcher.current = prevDispatcher;1535          }1536        }1537      }1538    }1539    if (__DEV__) {1540      // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests1541      if ('undefined' !== typeof jest) {1542        warnIfNotScopedWithMatchingAct(fiber);1543        warnIfNotCurrentlyActingUpdatesInDev(fiber);1544      }1545    }1546    scheduleUpdateOnFiber(fiber, lane, eventTime);1547  }1548  if (__DEV__) {1549    if (enableDebugTracing) {1550      if (fiber.mode & DebugTracingMode) {1551        const name = getComponentName(fiber.type) || 'Unknown';1552        logStateUpdateScheduled(name, lane, action);1553      }1554    }1555  }1556  if (enableSchedulingProfiler) {1557    markStateUpdateScheduled(fiber, lane);1558  }1559}1560export const ContextOnlyDispatcher             = {1561  readContext,1562  useCallback: throwInvalidHookError,1563  useContext: throwInvalidHookError,1564  useEffect: throwInvalidHookError,1565  useImperativeHandle: throwInvalidHookError,1566  useLayoutEffect: throwInvalidHookError,1567  useMemo: throwInvalidHookError,1568  useReducer: throwInvalidHookError,1569  useRef: throwInvalidHookError,1570  useState: throwInvalidHookError,1571  useDebugValue: throwInvalidHookError,1572  useDeferredValue: throwInvalidHookError,1573  useTransition: throwInvalidHookError,1574  useMutableSource: throwInvalidHookError,1575  useOpaqueIdentifier: throwInvalidHookError,1576  unstable_isNewReconciler: enableNewReconciler,1577};1578const HooksDispatcherOnMount             = {1579  readContext,1580  useCallback: mountCallback,1581  useContext: readContext,1582  useEffect: mountEffect,1583  useImperativeHandle: mountImperativeHandle,1584  useLayoutEffect: mountLayoutEffect,1585  useMemo: mountMemo,1586  useReducer: mountReducer,1587  useRef: mountRef,1588  useState: mountState,1589  useDebugValue: mountDebugValue,1590  useDeferredValue: mountDeferredValue,1591  useTransition: mountTransition,1592  useMutableSource: mountMutableSource,1593  useOpaqueIdentifier: mountOpaqueIdentifier,1594  unstable_isNewReconciler: enableNewReconciler,1595};1596const HooksDispatcherOnUpdate             = {1597  readContext,1598  useCallback: updateCallback,1599  useContext: readContext,1600  useEffect: updateEffect,1601  useImperativeHandle: updateImperativeHandle,1602  useLayoutEffect: updateLayoutEffect,1603  useMemo: updateMemo,1604  useReducer: updateReducer,1605  useRef: updateRef,1606  useState: updateState,1607  useDebugValue: updateDebugValue,1608  useDeferredValue: updateDeferredValue,1609  useTransition: updateTransition,1610  useMutableSource: updateMutableSource,1611  useOpaqueIdentifier: updateOpaqueIdentifier,1612  unstable_isNewReconciler: enableNewReconciler,1613};1614const HooksDispatcherOnRerender             = {1615  readContext,1616  useCallback: updateCallback,1617  useContext: readContext,1618  useEffect: updateEffect,1619  useImperativeHandle: updateImperativeHandle,1620  useLayoutEffect: updateLayoutEffect,1621  useMemo: updateMemo,1622  useReducer: rerenderReducer,1623  useRef: updateRef,1624  useState: rerenderState,1625  useDebugValue: updateDebugValue,1626  useDeferredValue: rerenderDeferredValue,1627  useTransition: rerenderTransition,1628  useMutableSource: updateMutableSource,1629  useOpaqueIdentifier: rerenderOpaqueIdentifier,1630  unstable_isNewReconciler: enableNewReconciler,1631};1632let HooksDispatcherOnMountInDEV                    = null;1633let HooksDispatcherOnMountWithHookTypesInDEV                    = null;1634let HooksDispatcherOnUpdateInDEV                    = null;1635let HooksDispatcherOnRerenderInDEV                    = null;1636let InvalidNestedHooksDispatcherOnMountInDEV                    = null;1637let InvalidNestedHooksDispatcherOnUpdateInDEV                    = null;1638let InvalidNestedHooksDispatcherOnRerenderInDEV                    = null;1639if (__DEV__) {1640  const warnInvalidContextAccess = () => {1641    console.error(1642      'Context can only be read while React is rendering. ' +1643        'In classes, you can read it in the render method or getDerivedStateFromProps. ' +1644        'In function components, you can read it directly in the function body, but not ' +1645        'inside Hooks like useReducer() or useMemo().',1646    );1647  };1648  const warnInvalidHookAccess = () => {1649    console.error(1650      'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' +1651        'You can only call Hooks at the top level of your React function. ' +1652        'For more information, see ' +1653        'https://reactjs.org/link/rules-of-hooks',1654    );1655  };1656  HooksDispatcherOnMountInDEV = {1657    readContext   (1658      context                 ,1659      observedBits                         ,1660    )    {1661      return readContext(context, observedBits);1662    },1663    useCallback   (callback   , deps                            )    {1664      currentHookNameInDev = 'useCallback';1665      mountHookTypesDev();1666      checkDepsAreArrayDev(deps);1667      return mountCallback(callback, deps);1668    },1669    useContext   (1670      context                 ,1671      observedBits                         ,1672    )    {1673      currentHookNameInDev = 'useContext';1674      mountHookTypesDev();1675      return readContext(context, observedBits);1676    },1677    useEffect(1678      create                           ,1679      deps                            ,1680    )       {1681      currentHookNameInDev = 'useEffect';1682      mountHookTypesDev();1683      checkDepsAreArrayDev(deps);1684      return mountEffect(create, deps);1685    },1686    useImperativeHandle   (1687      ref                                                                   ,1688      create         ,1689      deps                            ,1690    )       {1691      currentHookNameInDev = 'useImperativeHandle';1692      mountHookTypesDev();1693      checkDepsAreArrayDev(deps);1694      return mountImperativeHandle(ref, create, deps);1695    },1696    useLayoutEffect(1697      create                           ,1698      deps                            ,1699    )       {1700      currentHookNameInDev = 'useLayoutEffect';1701      mountHookTypesDev();1702      checkDepsAreArrayDev(deps);1703      return mountLayoutEffect(create, deps);1704    },1705    useMemo   (create         , deps                            )    {1706      currentHookNameInDev = 'useMemo';1707      mountHookTypesDev();1708      checkDepsAreArrayDev(deps);1709      const prevDispatcher = ReactCurrentDispatcher.current;1710      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1711      try {1712        return mountMemo(create, deps);1713      } finally {1714        ReactCurrentDispatcher.current = prevDispatcher;1715      }1716    },1717    useReducer         (1718      reducer             ,1719      initialArg   ,1720      init         ,1721    )                   {1722      currentHookNameInDev = 'useReducer';1723      mountHookTypesDev();1724      const prevDispatcher = ReactCurrentDispatcher.current;1725      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1726      try {1727        return mountReducer(reducer, initialArg, init);1728      } finally {1729        ReactCurrentDispatcher.current = prevDispatcher;1730      }1731    },1732    useRef   (initialValue   )                 {1733      currentHookNameInDev = 'useRef';1734      mountHookTypesDev();1735      return mountRef(initialValue);1736    },1737    useState   (1738      initialState               ,1739    )                                     {1740      currentHookNameInDev = 'useState';1741      mountHookTypesDev();1742      const prevDispatcher = ReactCurrentDispatcher.current;1743      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1744      try {1745        return mountState(initialState);1746      } finally {1747        ReactCurrentDispatcher.current = prevDispatcher;1748      }1749    },1750    useDebugValue   (value   , formatterFn                      )       {1751      currentHookNameInDev = 'useDebugValue';1752      mountHookTypesDev();1753      return mountDebugValue(value, formatterFn);1754    },1755    useDeferredValue   (value   )    {1756      currentHookNameInDev = 'useDeferredValue';1757      mountHookTypesDev();1758      return mountDeferredValue(value);1759    },1760    useTransition()                                  {1761      currentHookNameInDev = 'useTransition';1762      mountHookTypesDev();1763      return mountTransition();1764    },1765    useMutableSource                  (1766      source                       ,1767      getSnapshot                                              ,1768      subscribe                                            ,1769    )           {1770      currentHookNameInDev = 'useMutableSource';1771      mountHookTypesDev();1772      return mountMutableSource(source, getSnapshot, subscribe);1773    },1774    useOpaqueIdentifier()                      {1775      currentHookNameInDev = 'useOpaqueIdentifier';1776      mountHookTypesDev();1777      return mountOpaqueIdentifier();1778    },1779    unstable_isNewReconciler: enableNewReconciler,1780  };1781  HooksDispatcherOnMountWithHookTypesInDEV = {1782    readContext   (1783      context                 ,1784      observedBits                         ,1785    )    {1786      return readContext(context, observedBits);1787    },1788    useCallback   (callback   , deps                            )    {1789      currentHookNameInDev = 'useCallback';1790      updateHookTypesDev();1791      return mountCallback(callback, deps);1792    },1793    useContext   (1794      context                 ,1795      observedBits                         ,1796    )    {1797      currentHookNameInDev = 'useContext';1798      updateHookTypesDev();1799      return readContext(context, observedBits);1800    },1801    useEffect(1802      create                           ,1803      deps                            ,1804    )       {1805      currentHookNameInDev = 'useEffect';1806      updateHookTypesDev();1807      return mountEffect(create, deps);1808    },1809    useImperativeHandle   (1810      ref                                                                   ,1811      create         ,1812      deps                            ,1813    )       {1814      currentHookNameInDev = 'useImperativeHandle';1815      updateHookTypesDev();1816      return mountImperativeHandle(ref, create, deps);1817    },1818    useLayoutEffect(1819      create                           ,1820      deps                            ,1821    )       {1822      currentHookNameInDev = 'useLayoutEffect';1823      updateHookTypesDev();1824      return mountLayoutEffect(create, deps);1825    },1826    useMemo   (create         , deps                            )    {1827      currentHookNameInDev = 'useMemo';1828      updateHookTypesDev();1829      const prevDispatcher = ReactCurrentDispatcher.current;1830      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1831      try {1832        return mountMemo(create, deps);1833      } finally {1834        ReactCurrentDispatcher.current = prevDispatcher;1835      }1836    },1837    useReducer         (1838      reducer             ,1839      initialArg   ,1840      init         ,1841    )                   {1842      currentHookNameInDev = 'useReducer';1843      updateHookTypesDev();1844      const prevDispatcher = ReactCurrentDispatcher.current;1845      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1846      try {1847        return mountReducer(reducer, initialArg, init);1848      } finally {1849        ReactCurrentDispatcher.current = prevDispatcher;1850      }1851    },1852    useRef   (initialValue   )                 {1853      currentHookNameInDev = 'useRef';1854      updateHookTypesDev();1855      return mountRef(initialValue);1856    },1857    useState   (1858      initialState               ,1859    )                                     {1860      currentHookNameInDev = 'useState';1861      updateHookTypesDev();1862      const prevDispatcher = ReactCurrentDispatcher.current;1863      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;1864      try {1865        return mountState(initialState);1866      } finally {1867        ReactCurrentDispatcher.current = prevDispatcher;1868      }1869    },1870    useDebugValue   (value   , formatterFn                      )       {1871      currentHookNameInDev = 'useDebugValue';1872      updateHookTypesDev();1873      return mountDebugValue(value, formatterFn);1874    },1875    useDeferredValue   (value   )    {1876      currentHookNameInDev = 'useDeferredValue';1877      updateHookTypesDev();1878      return mountDeferredValue(value);1879    },1880    useTransition()                                  {1881      currentHookNameInDev = 'useTransition';1882      updateHookTypesDev();1883      return mountTransition();1884    },1885    useMutableSource                  (1886      source                       ,1887      getSnapshot                                              ,1888      subscribe                                            ,1889    )           {1890      currentHookNameInDev = 'useMutableSource';1891      updateHookTypesDev();1892      return mountMutableSource(source, getSnapshot, subscribe);1893    },1894    useOpaqueIdentifier()                      {1895      currentHookNameInDev = 'useOpaqueIdentifier';1896      updateHookTypesDev();1897      return mountOpaqueIdentifier();1898    },1899    unstable_isNewReconciler: enableNewReconciler,1900  };1901  HooksDispatcherOnUpdateInDEV = {1902    readContext   (1903      context                 ,1904      observedBits                         ,1905    )    {1906      return readContext(context, observedBits);1907    },1908    useCallback   (callback   , deps                            )    {1909      currentHookNameInDev = 'useCallback';1910      updateHookTypesDev();1911      return updateCallback(callback, deps);1912    },1913    useContext   (1914      context                 ,1915      observedBits                         ,1916    )    {1917      currentHookNameInDev = 'useContext';1918      updateHookTypesDev();1919      return readContext(context, observedBits);1920    },1921    useEffect(1922      create                           ,1923      deps                            ,1924    )       {1925      currentHookNameInDev = 'useEffect';1926      updateHookTypesDev();1927      return updateEffect(create, deps);1928    },1929    useImperativeHandle   (1930      ref                                                                   ,1931      create         ,1932      deps                            ,1933    )       {1934      currentHookNameInDev = 'useImperativeHandle';1935      updateHookTypesDev();1936      return updateImperativeHandle(ref, create, deps);1937    },1938    useLayoutEffect(1939      create                           ,1940      deps                            ,1941    )       {1942      currentHookNameInDev = 'useLayoutEffect';1943      updateHookTypesDev();1944      return updateLayoutEffect(create, deps);1945    },1946    useMemo   (create         , deps                            )    {1947      currentHookNameInDev = 'useMemo';1948      updateHookTypesDev();1949      const prevDispatcher = ReactCurrentDispatcher.current;1950      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;1951      try {1952        return updateMemo(create, deps);1953      } finally {1954        ReactCurrentDispatcher.current = prevDispatcher;1955      }1956    },1957    useReducer         (1958      reducer             ,1959      initialArg   ,1960      init         ,1961    )                   {1962      currentHookNameInDev = 'useReducer';1963      updateHookTypesDev();1964      const prevDispatcher = ReactCurrentDispatcher.current;1965      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;1966      try {1967        return updateReducer(reducer, initialArg, init);1968      } finally {1969        ReactCurrentDispatcher.current = prevDispatcher;1970      }1971    },1972    useRef   (initialValue   )                 {1973      currentHookNameInDev = 'useRef';1974      updateHookTypesDev();1975      return updateRef(initialValue);1976    },1977    useState   (1978      initialState               ,1979    )                                     {1980      currentHookNameInDev = 'useState';1981      updateHookTypesDev();1982      const prevDispatcher = ReactCurrentDispatcher.current;1983      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;1984      try {1985        return updateState(initialState);1986      } finally {1987        ReactCurrentDispatcher.current = prevDispatcher;1988      }1989    },1990    useDebugValue   (value   , formatterFn                      )       {1991      currentHookNameInDev = 'useDebugValue';1992      updateHookTypesDev();1993      return updateDebugValue(value, formatterFn);1994    },1995    useDeferredValue   (value   )    {1996      currentHookNameInDev = 'useDeferredValue';1997      updateHookTypesDev();1998      return updateDeferredValue(value);1999    },2000    useTransition()                                  {2001      currentHookNameInDev = 'useTransition';2002      updateHookTypesDev();2003      return updateTransition();2004    },2005    useMutableSource                  (2006      source                       ,2007      getSnapshot                                              ,2008      subscribe                                            ,2009    )           {2010      currentHookNameInDev = 'useMutableSource';2011      updateHookTypesDev();2012      return updateMutableSource(source, getSnapshot, subscribe);2013    },2014    useOpaqueIdentifier()                      {2015      currentHookNameInDev = 'useOpaqueIdentifier';2016      updateHookTypesDev();2017      return updateOpaqueIdentifier();2018    },2019    unstable_isNewReconciler: enableNewReconciler,2020  };2021  HooksDispatcherOnRerenderInDEV = {2022    readContext   (2023      context                 ,2024      observedBits                         ,2025    )    {2026      return readContext(context, observedBits);2027    },2028    useCallback   (callback   , deps                            )    {2029      currentHookNameInDev = 'useCallback';2030      updateHookTypesDev();2031      return updateCallback(callback, deps);2032    },2033    useContext   (2034      context                 ,2035      observedBits                         ,2036    )    {2037      currentHookNameInDev = 'useContext';2038      updateHookTypesDev();2039      return readContext(context, observedBits);2040    },2041    useEffect(2042      create                           ,2043      deps                            ,2044    )       {2045      currentHookNameInDev = 'useEffect';2046      updateHookTypesDev();2047      return updateEffect(create, deps);2048    },2049    useImperativeHandle   (2050      ref                                                                   ,2051      create         ,2052      deps                            ,2053    )       {2054      currentHookNameInDev = 'useImperativeHandle';2055      updateHookTypesDev();2056      return updateImperativeHandle(ref, create, deps);2057    },2058    useLayoutEffect(2059      create                           ,2060      deps                            ,2061    )       {2062      currentHookNameInDev = 'useLayoutEffect';2063      updateHookTypesDev();2064      return updateLayoutEffect(create, deps);2065    },2066    useMemo   (create         , deps                            )    {2067      currentHookNameInDev = 'useMemo';2068      updateHookTypesDev();2069      const prevDispatcher = ReactCurrentDispatcher.current;2070      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;2071      try {2072        return updateMemo(create, deps);2073      } finally {2074        ReactCurrentDispatcher.current = prevDispatcher;2075      }2076    },2077    useReducer         (2078      reducer             ,2079      initialArg   ,2080      init         ,2081    )                   {2082      currentHookNameInDev = 'useReducer';2083      updateHookTypesDev();2084      const prevDispatcher = ReactCurrentDispatcher.current;2085      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;2086      try {2087        return rerenderReducer(reducer, initialArg, init);2088      } finally {2089        ReactCurrentDispatcher.current = prevDispatcher;2090      }2091    },2092    useRef   (initialValue   )                 {2093      currentHookNameInDev = 'useRef';2094      updateHookTypesDev();2095      return updateRef(initialValue);2096    },2097    useState   (2098      initialState               ,2099    )                                     {2100      currentHookNameInDev = 'useState';2101      updateHookTypesDev();2102      const prevDispatcher = ReactCurrentDispatcher.current;2103      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnRerenderInDEV;2104      try {2105        return rerenderState(initialState);2106      } finally {2107        ReactCurrentDispatcher.current = prevDispatcher;2108      }2109    },2110    useDebugValue   (value   , formatterFn                      )       {2111      currentHookNameInDev = 'useDebugValue';2112      updateHookTypesDev();2113      return updateDebugValue(value, formatterFn);2114    },2115    useDeferredValue   (value   )    {2116      currentHookNameInDev = 'useDeferredValue';2117      updateHookTypesDev();2118      return rerenderDeferredValue(value);2119    },2120    useTransition()                                  {2121      currentHookNameInDev = 'useTransition';2122      updateHookTypesDev();2123      return rerenderTransition();2124    },2125    useMutableSource                  (2126      source                       ,2127      getSnapshot                                              ,2128      subscribe                                            ,2129    )           {2130      currentHookNameInDev = 'useMutableSource';2131      updateHookTypesDev();2132      return updateMutableSource(source, getSnapshot, subscribe);2133    },2134    useOpaqueIdentifier()                      {2135      currentHookNameInDev = 'useOpaqueIdentifier';2136      updateHookTypesDev();2137      return rerenderOpaqueIdentifier();2138    },2139    unstable_isNewReconciler: enableNewReconciler,2140  };2141  InvalidNestedHooksDispatcherOnMountInDEV = {2142    readContext   (2143      context                 ,2144      observedBits                         ,2145    )    {2146      warnInvalidContextAccess();2147      return readContext(context, observedBits);2148    },2149    useCallback   (callback   , deps                            )    {2150      currentHookNameInDev = 'useCallback';2151      warnInvalidHookAccess();2152      mountHookTypesDev();2153      return mountCallback(callback, deps);2154    },2155    useContext   (2156      context                 ,2157      observedBits                         ,2158    )    {2159      currentHookNameInDev = 'useContext';2160      warnInvalidHookAccess();2161      mountHookTypesDev();2162      return readContext(context, observedBits);2163    },2164    useEffect(2165      create                           ,2166      deps                            ,2167    )       {2168      currentHookNameInDev = 'useEffect';2169      warnInvalidHookAccess();2170      mountHookTypesDev();2171      return mountEffect(create, deps);2172    },2173    useImperativeHandle   (2174      ref                                                                   ,2175      create         ,2176      deps                            ,2177    )       {2178      currentHookNameInDev = 'useImperativeHandle';2179      warnInvalidHookAccess();2180      mountHookTypesDev();2181      return mountImperativeHandle(ref, create, deps);2182    },2183    useLayoutEffect(2184      create                           ,2185      deps                            ,2186    )       {2187      currentHookNameInDev = 'useLayoutEffect';2188      warnInvalidHookAccess();2189      mountHookTypesDev();2190      return mountLayoutEffect(create, deps);2191    },2192    useMemo   (create         , deps                            )    {2193      currentHookNameInDev = 'useMemo';2194      warnInvalidHookAccess();2195      mountHookTypesDev();2196      const prevDispatcher = ReactCurrentDispatcher.current;2197      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;2198      try {2199        return mountMemo(create, deps);2200      } finally {2201        ReactCurrentDispatcher.current = prevDispatcher;2202      }2203    },2204    useReducer         (2205      reducer             ,2206      initialArg   ,2207      init         ,2208    )                   {2209      currentHookNameInDev = 'useReducer';2210      warnInvalidHookAccess();2211      mountHookTypesDev();2212      const prevDispatcher = ReactCurrentDispatcher.current;2213      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;2214      try {2215        return mountReducer(reducer, initialArg, init);2216      } finally {2217        ReactCurrentDispatcher.current = prevDispatcher;2218      }2219    },2220    useRef   (initialValue   )                 {2221      currentHookNameInDev = 'useRef';2222      warnInvalidHookAccess();2223      mountHookTypesDev();2224      return mountRef(initialValue);2225    },2226    useState   (2227      initialState               ,2228    )                                     {2229      currentHookNameInDev = 'useState';2230      warnInvalidHookAccess();2231      mountHookTypesDev();2232      const prevDispatcher = ReactCurrentDispatcher.current;2233      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnMountInDEV;2234      try {2235        return mountState(initialState);2236      } finally {2237        ReactCurrentDispatcher.current = prevDispatcher;2238      }2239    },2240    useDebugValue   (value   , formatterFn                      )       {2241      currentHookNameInDev = 'useDebugValue';2242      warnInvalidHookAccess();2243      mountHookTypesDev();2244      return mountDebugValue(value, formatterFn);2245    },2246    useDeferredValue   (value   )    {2247      currentHookNameInDev = 'useDeferredValue';2248      warnInvalidHookAccess();2249      mountHookTypesDev();2250      return mountDeferredValue(value);2251    },2252    useTransition()                                  {2253      currentHookNameInDev = 'useTransition';2254      warnInvalidHookAccess();2255      mountHookTypesDev();2256      return mountTransition();2257    },2258    useMutableSource                  (2259      source                       ,2260      getSnapshot                                              ,2261      subscribe                                            ,2262    )           {2263      currentHookNameInDev = 'useMutableSource';2264      warnInvalidHookAccess();2265      mountHookTypesDev();2266      return mountMutableSource(source, getSnapshot, subscribe);2267    },2268    useOpaqueIdentifier()                      {2269      currentHookNameInDev = 'useOpaqueIdentifier';2270      warnInvalidHookAccess();2271      mountHookTypesDev();2272      return mountOpaqueIdentifier();2273    },2274    unstable_isNewReconciler: enableNewReconciler,2275  };2276  InvalidNestedHooksDispatcherOnUpdateInDEV = {2277    readContext   (2278      context                 ,2279      observedBits                         ,2280    )    {2281      warnInvalidContextAccess();2282      return readContext(context, observedBits);2283    },2284    useCallback   (callback   , deps                            )    {2285      currentHookNameInDev = 'useCallback';2286      warnInvalidHookAccess();2287      updateHookTypesDev();2288      return updateCallback(callback, deps);2289    },2290    useContext   (2291      context                 ,2292      observedBits                         ,2293    )    {2294      currentHookNameInDev = 'useContext';2295      warnInvalidHookAccess();2296      updateHookTypesDev();2297      return readContext(context, observedBits);2298    },2299    useEffect(2300      create                           ,2301      deps                            ,2302    )       {2303      currentHookNameInDev = 'useEffect';2304      warnInvalidHookAccess();2305      updateHookTypesDev();2306      return updateEffect(create, deps);2307    },2308    useImperativeHandle   (2309      ref                                                                   ,2310      create         ,2311      deps                            ,2312    )       {2313      currentHookNameInDev = 'useImperativeHandle';2314      warnInvalidHookAccess();2315      updateHookTypesDev();2316      return updateImperativeHandle(ref, create, deps);2317    },2318    useLayoutEffect(2319      create                           ,2320      deps                            ,2321    )       {2322      currentHookNameInDev = 'useLayoutEffect';2323      warnInvalidHookAccess();2324      updateHookTypesDev();2325      return updateLayoutEffect(create, deps);2326    },2327    useMemo   (create         , deps                            )    {2328      currentHookNameInDev = 'useMemo';2329      warnInvalidHookAccess();2330      updateHookTypesDev();2331      const prevDispatcher = ReactCurrentDispatcher.current;2332      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;2333      try {2334        return updateMemo(create, deps);2335      } finally {2336        ReactCurrentDispatcher.current = prevDispatcher;2337      }2338    },2339    useReducer         (2340      reducer             ,2341      initialArg   ,2342      init         ,2343    )                   {2344      currentHookNameInDev = 'useReducer';2345      warnInvalidHookAccess();2346      updateHookTypesDev();2347      const prevDispatcher = ReactCurrentDispatcher.current;2348      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;2349      try {2350        return updateReducer(reducer, initialArg, init);2351      } finally {2352        ReactCurrentDispatcher.current = prevDispatcher;2353      }2354    },2355    useRef   (initialValue   )                 {2356      currentHookNameInDev = 'useRef';2357      warnInvalidHookAccess();2358      updateHookTypesDev();2359      return updateRef(initialValue);2360    },2361    useState   (2362      initialState               ,2363    )                                     {2364      currentHookNameInDev = 'useState';2365      warnInvalidHookAccess();2366      updateHookTypesDev();2367      const prevDispatcher = ReactCurrentDispatcher.current;2368      ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;2369      try {2370        return updateState(initialState);2371      } finally {2372        ReactCurrentDispatcher.current = prevDispatcher;2373      }2374    },2375    useDebugValue   (value   , formatterFn                      )       {2376      currentHookNameInDev = 'useDebugValue';2377      warnInvalidHookAccess();2378      updateHookTypesDev();2379      return updateDebugValue(value, formatterFn);2380    },2381    useDeferredValue   (value   )    {2382      currentHookNameInDev = 'useDeferredValue';2383      warnInvalidHookAccess();2384      updateHookTypesDev();2385      return updateDeferredValue(value);2386    },2387    useTransition()                                  {2388      currentHookNameInDev = 'useTransition';2389      warnInvalidHookAccess();2390      updateHookTypesDev();2391      return updateTransition();2392    },2393    useMutableSource                  (2394      source                       ,2395      getSnapshot                                              ,2396      subscribe                                            ,2397    )           {2398      currentHookNameInDev = 'useMutableSource';2399      warnInvalidHookAccess();2400      updateHookTypesDev();2401      return updateMutableSource(source, getSnapshot, subscribe);2402    },2403    useOpaqueIdentifier()                      {2404      currentHookNameInDev = 'useOpaqueIdentifier';2405      warnInvalidHookAccess();2406      updateHookTypesDev();2407      return updateOpaqueIdentifier();2408    },2409    unstable_isNewReconciler: enableNewReconciler,2410  };2411  InvalidNestedHooksDispatcherOnRerenderInDEV = {2412    readContext   (2413      context                 ,2414      observedBits                         ,2415    )    {2416      warnInvalidContextAccess();2417      return readContext(context, observedBits);2418    },2419    useCallback   (callback   , deps                            )    {2420      currentHookNameInDev = 'useCallback';2421      warnInvalidHookAccess();...ReactFiberHooks.js
Source:ReactFiberHooks.js  
1import ReactCurrentDispatcher from "../react/ReactCurrentDispatcher";2import { requestEventTime, requestUpdateLane } from "./ReactFiberWorkLoop";3import {4  Update as UpdateEffect,5  Passive as PassiveEffect,6} from "./ReactFiberFlags";7import {8  HasEffect as HookHasEffect,9  Layout as HookLayout,10  Passive as HookPassive,11} from "./ReactHookEffectTags";12// The work-in-progress fiber. I've named it differently to distinguish it from13// the work-in-progress hook.14let currentlyRenderingFiber = null;15// Hooks are stored as a linked list on the fiber's memoizedState field. The16// current hook list is the list that belongs to the current fiber. The17// work-in-progress hook list is a new list that will be added to the18// work-in-progress fiber.19// Hooks ç¨é¾è¡¨ç»æï¼ åè´®å¨fiber's memoizedStateåæ®µ20// Hook | null21let currentHook = null;22// Hook | null23let workInProgressHook = null;24// Whether an update was scheduled at any point during the render phase. This25// does not get reset if we do another render pass; only when we're completely26// finished evaluating this component. This is an optimization so we know27// whether we need to clear render phase updates after a throw.28let didScheduleRenderPhaseUpdate = false;29// Where an update was scheduled only during the current render pass. This30// gets reset after each attempt.31// TODO: Maybe there's some way to consolidate this with32// `didScheduleRenderPhaseUpdate`. Or with `numberOfReRenders`.33let didScheduleRenderPhaseUpdateDuringThisPass = false;34export function renderWithHooks(35  // null36  current,37  workInProgress,38  // è¿éæ¯å½æ°ç»ä»¶ï¼ å
¶å®å°±æ¯wip.type39  Component,40  // wip.props41  props,42  // context43  secondArg,44  nextRenderLanes45) {46  renderLanes = nextRenderLanes;47  currentlyRenderingFiber = workInProgress;48  // 为ä½è¿è¾¹å°±å·²ç»æ¸
空 memoizedState å updateQueue äº?49  workInProgress.memoizedState = null;50  workInProgress.updateQueue = null;51  workInProgress.lanes = NoLanes;52  // The following should have already been reset53  // currentHook = null;54  // workInProgressHook = null;55  // didScheduleRenderPhaseUpdate = false;56  // TODO Warn if no hooks are used at all during mount, then some are used during update.57  // Currently we will identify the update render as a mount because memoizedState === null.58  // This is tricky because it's valid for certain types of components (e.g. React.lazy)59  // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used.60  // Non-stateful hooks (e.g. context) don't get added to memoizedState,61  // so memoizedState would be null during updates and mounts.62  // Dispatcher è·useStateæå
³63  ReactCurrentDispatcher.current =64    current === null || current.memoizedState === null65      ? HooksDispatcherOnMount66      : HooksDispatcherOnUpdate;67  // ç´æ¥æ§è¡ç»ä»¶å½æ°, å¾å°ä¸ä¸ª jsx object68  let children = Component(props, secondArg);69  // Check if there was a render phase update70  if (didScheduleRenderPhaseUpdateDuringThisPass) {71    // Keep rendering in a loop for as long as render phase updates continue to72    // be scheduled. Use a counter to prevent infinite loops.73    let numberOfReRenders = 0;74    do {75      didScheduleRenderPhaseUpdateDuringThisPass = false;76      invariant(77        numberOfReRenders < RE_RENDER_LIMIT,78        "Too many re-renders. React limits the number of renders to prevent " +79          "an infinite loop."80      );81      numberOfReRenders += 1;82      // Start over from the beginning of the list83      currentHook = null;84      workInProgressHook = null;85      workInProgress.updateQueue = null;86      ReactCurrentDispatcher.current = HooksDispatcherOnRerender;87      children = Component(props, secondArg);88    } while (didScheduleRenderPhaseUpdateDuringThisPass);89  }90  // We can assume the previous dispatcher is always this one, since we set it91  // at the beginning of the render phase and there's no re-entrancy.92  ReactCurrentDispatcher.current = ContextOnlyDispatcher;93  // This check uses currentHook so that it works the same in DEV and prod bundles.94  // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.95  const didRenderTooFewHooks =96    currentHook !== null && currentHook.next !== null;97  renderLanes = NoLanes;98  currentlyRenderingFiber = null;99  currentHook = null;100  workInProgressHook = null;101  didScheduleRenderPhaseUpdate = false;102  invariant(103    !didRenderTooFewHooks,104    "Rendered fewer hooks than expected. This may be caused by an accidental " +105      "early return statement."106  );107  return children;108}109function mountWorkInProgressHook() {110  const hook = {111    memoizedState: null,112    baseState: null,113    baseQueue: null,114    queue: null,115    next: null,116  };117  if (workInProgressHook === null) {118    // This is the first hook in the list119    currentlyRenderingFiber.memoizedState = workInProgressHook = hook;120  } else {121    // ä¸ä¸ªå½æ°ç»ä»¶éé¢ï¼ 两个以ä¸çhook就走è¿éï¼ é¾èµ·æ¥äº~122    // Append to the end of the list123    workInProgressHook = workInProgressHook.next = hook;124  }125  return workInProgressHook;126}127function createFunctionComponentUpdateQueue() {128  return {129    lastEffect: null,130  };131}132/**133 * ætag为 HookHasEffect|HookPassiveçeffectåå
¥fiber.updateQueue134 */135function pushEffect(tag, create, destroy, deps) {136  const effect = {137    tag,138    create,139    destroy,140    deps,141    // Circular142    next: null,143  };144  // 卿å¦ä¹ çä¾åé, è¿ä¸ªfiberæ¯App彿°ç»ä»¶, 对åºçfiberèç¹æ¯æ²¡æupdateQueueç(åå»ºçæ¶å就没æåå§å)145  let componentUpdateQueue = currentlyRenderingFiber.updateQueue;146  if (componentUpdateQueue === null) {147    componentUpdateQueue = createFunctionComponentUpdateQueue();148    currentlyRenderingFiber.updateQueue = componentUpdateQueue;149    componentUpdateQueue.lastEffect = effect.next = effect;150  } else {151    // è¿éè·updateQueue.shared.pendingé£ä¸ªåå¾ªç¯æäºä¸ä¸æ ·,152    const lastEffect = componentUpdateQueue.lastEffect;153    if (lastEffect === null) {154      componentUpdateQueue.lastEffect = effect.next = effect;155    } else {156      const firstEffect = lastEffect.next;157      lastEffect.next = effect;158      effect.next = firstEffect;159      componentUpdateQueue.lastEffect = effect;160    }161  }162  return effect;163}164function mountEffectImpl(fiberFlags, hookFlags, create, deps) {165  const hook = mountWorkInProgressHook();166  const nextDeps = deps === undefined ? null : deps;167  // å¦å¼ï¼ å°±å¨è¿ï¼ è¿ä¸ªfiberä¸æäº PassiveEffect168  // 卿å¦çä¾åéï¼ å¯¹äºcomponent App, å
¶flagså¨åå»ºçæ¶å169  // ç± placeSingleChild 彿°æä¸ Placement = 2170  // è¿éåè· UpdateEffect | PassiveEffect ååå¹¶171  currentlyRenderingFiber.flags |= fiberFlags;172  // åªæ¯åå
¥updateQueue, **并䏿§è¡**173  // 注æ, è¿édestroyææ¶ä¸ºundefined, å ä¸ºdestroy彿°æ¯create彿°çè¿åå¼174  hook.memoizedState = pushEffect(175    HookHasEffect | hookFlags,176    create,177    undefined,178    nextDeps179  );180}181function mountEffect(create, deps) {182  return mountEffectImpl(183    UpdateEffect | PassiveEffect,184    HookPassive,185    create,186    deps187  );188}189function mountState(initialState) {190  // wip.memoizedState å¡ä¸ä¸ªç©ºçhook对象ï¼ä½ä¸ºhookåé¾è¡¨çèµ·ç¹(?)191  const hook = mountWorkInProgressHook();192  if (typeof initialState === "function") {193    // useStateçåå§ç¶ææ¯å½æ°ï¼ è¿éæ§è¡å½æ°ï¼ è¿åå¼èµå¼ç»initialState194    initialState = initialState();195  }196  hook.memoizedState = hook.baseState = initialState;197  const queue = (hook.queue = {198    pending: null,199    dispatch: null,200    lastRenderedReducer: basicStateReducer,201    lastRenderedState: initialState,202  });203  // const [a, setA] = useState('a')204  // setA å°±æ¯è¿éç dispatchAction205  const dispatch = (queue.dispatch = dispatchAction.bind(206    null,207    currentlyRenderingFiber,208    queue209  ));210  return [hook.memoizedState, dispatch];211}212// è¿å½æ°å头åç213function dispatchAction(fiber, queue, action) {214  const eventTime = requestEventTime();215  const lane = requestUpdateLane(fiber);216  const update = {217    lane,218    action,219    eagerReducer: null,220    eagerState: null,221    next: null,222  };223  // Append the update to the end of the list.224  const pending = queue.pending;225  if (pending === null) {226    // This is the first update. Create a circular list.227    update.next = update;228  } else {229    update.next = pending.next;230    pending.next = update;231  }232  queue.pending = update;233  const alternate = fiber.alternate;234  if (235    fiber === currentlyRenderingFiber ||236    (alternate !== null && alternate === currentlyRenderingFiber)237  ) {238    // This is a render phase update. Stash it in a lazily-created map of239    // queue -> linked list of updates. After this render pass, we'll restart240    // and apply the stashed updates on top of the work-in-progress hook.241    didScheduleRenderPhaseUpdateDuringThisPass =242      didScheduleRenderPhaseUpdate = true;243  } else {244    if (245      fiber.lanes === NoLanes &&246      (alternate === null || alternate.lanes === NoLanes)247    ) {248      // The queue is currently empty, which means we can eagerly compute the249      // next state before entering the render phase. If the new state is the250      // same as the current state, we may be able to bail out entirely.251      const lastRenderedReducer = queue.lastRenderedReducer;252      if (lastRenderedReducer !== null) {253        let prevDispatcher;254        try {255          const currentState = queue.lastRenderedState;256          const eagerState = lastRenderedReducer(currentState, action);257          // Stash the eagerly computed state, and the reducer used to compute258          // it, on the update object. If the reducer hasn't changed by the259          // time we enter the render phase, then the eager state can be used260          // without calling the reducer again.261          update.eagerReducer = lastRenderedReducer;262          update.eagerState = eagerState;263          if (is(eagerState, currentState)) {264            // Fast path. We can bail out without scheduling React to re-render.265            // It's still possible that we'll need to rebase this update later,266            // if the component re-renders for a different reason and by that267            // time the reducer has changed.268            return;269          }270        } catch (error) {271          // Suppress the error. It will throw again in the render phase.272        }273      }274    }275    // å¼å§renderé¶æ®µå¯276    scheduleUpdateOnFiber(fiber, lane, eventTime);277  }278}279export const ContextOnlyDispatcher = {280  readContext,281  useCallback: throwInvalidHookError,282  useContext: throwInvalidHookError,283  useEffect: throwInvalidHookError,284  useImperativeHandle: throwInvalidHookError,285  useLayoutEffect: throwInvalidHookError,286  useMemo: throwInvalidHookError,287  useReducer: throwInvalidHookError,288  useRef: throwInvalidHookError,289  useState: throwInvalidHookError,290  useDebugValue: throwInvalidHookError,291  useDeferredValue: throwInvalidHookError,292  useTransition: throwInvalidHookError,293  useMutableSource: throwInvalidHookError,294  useOpaqueIdentifier: throwInvalidHookError,295  unstable_isNewReconciler: enableNewReconciler,296};297const HooksDispatcherOnMount = {298  readContext,299  useCallback: mountCallback,300  useContext: readContext,301  useEffect: mountEffect,302  useImperativeHandle: mountImperativeHandle,303  useLayoutEffect: mountLayoutEffect,304  useMemo: mountMemo,305  useReducer: mountReducer,306  useRef: mountRef,307  useState: mountState,308  useDebugValue: mountDebugValue,309  useDeferredValue: mountDeferredValue,310  useTransition: mountTransition,311  useMutableSource: mountMutableSource,312  useOpaqueIdentifier: mountOpaqueIdentifier,313  unstable_isNewReconciler: enableNewReconciler,314};315const HooksDispatcherOnUpdate = {316  readContext,317  useCallback: updateCallback,318  useContext: readContext,319  useEffect: updateEffect,320  useImperativeHandle: updateImperativeHandle,321  useLayoutEffect: updateLayoutEffect,322  useMemo: updateMemo,323  useReducer: updateReducer,324  useRef: updateRef,325  useState: updateState,326  useDebugValue: updateDebugValue,327  useDeferredValue: updateDeferredValue,328  useTransition: updateTransition,329  useMutableSource: updateMutableSource,330  useOpaqueIdentifier: updateOpaqueIdentifier,331  unstable_isNewReconciler: enableNewReconciler,332};333const HooksDispatcherOnRerender = {334  readContext,335  useCallback: updateCallback,336  useContext: readContext,337  useEffect: updateEffect,338  useImperativeHandle: updateImperativeHandle,339  useLayoutEffect: updateLayoutEffect,340  useMemo: updateMemo,341  useReducer: rerenderReducer,342  useRef: updateRef,343  useState: rerenderState,344  useDebugValue: updateDebugValue,345  useDeferredValue: rerenderDeferredValue,346  useTransition: rerenderTransition,347  useMutableSource: updateMutableSource,348  useOpaqueIdentifier: rerenderOpaqueIdentifier,349  unstable_isNewReconciler: enableNewReconciler,...Using AI Code Generation
1const { chromium } = require('playwright');2(async () => {3  const browser = await chromium.launch();4  const context = await browser.newContext();5  const page = await context.newPage();6  await page.route('**', (route) => {7    if (route.request().url().endsWith('png')) {8      route.fulfill({9        headers: {10        },11      });12    } else {13      route.continue();14    }15  });16  await page.screenshot({ path: 'google.png' });17  await browser.close();18})();19const { chromium } = require('playwright');20(async () => {21  const browser = await chromium.launch();22  const context = await browser.newContext();23  const page = await context.newPage();24  await page.route('**', (route) => {25    if (route.request().url().endsWith('png')) {26      route.fulfill({27        headers: {28        },29      });30    } else {31      route.continue();32    }33  });34  await page.screenshot({ path: 'google.png' });35  await browser.close();36})();37const { chromium } = require('playwright');38(async () => {39  const browser = await chromium.launch();40  const context = await browser.newContext();41  const page = await context.newPage();42  await page.route('**', (route) => {43    if (route.request().url().endsWith('png')) {44      route.fulfill({45        headers: {46        },47      });48    } else {49      route.continue();50    }51  });52  await page.screenshot({ path: 'google.png' });53  await browser.close();54})();55const { chromium } = require('playwright');56(async () => {57  const browser = await chromium.launch();Using AI Code Generation
1const { updateOpaqueIdentifier } = require('@playwright/test/lib/server/frames');2const { chromium } = require('playwright');3(async () => {4  const browser = await chromium.launch();5  const context = await browser.newContext();6  const page = await context.newPage();7  const elementHandle = await page.$('.navbar__inner .navbar__title');8  const element = await elementHandle._element;9  await updateOpaqueIdentifier(element, 'test-id');10  await browser.close();11})();12const { test, expect } = require('@playwright/test');13test('test', async ({ page }) => {14  const elementHandle = await page.$('.navbar__inner .navbar__title');15  const element = await elementHandle._element;16  const id = await element.evaluate(element => element.getAttribute('id'));17  expect(id).toBe('test-id');18});Using AI Code Generation
1const { updateOpaqueIdentifier } = require('@playwright/test/lib/server/frames');2const { chromium } = require('playwright');3(async () => {4  const browser = await chromium.launch();5  const context = await browser.newContext();6  const page = await context.newPage();7  const element = await page.$('text="Get Started"');8  await updateOpaqueIdentifier(element, 'foo');9  const updatedElement = await page.$('foo');10  console.log(await updatedElement.textContent());11  await browser.close();12})();13const { test } = require('@playwright/test');14test('test', async ({ page }) => {15  const element = await page.$('text="Get Started"');16  await updateOpaqueIdentifier(element, 'foo');17  const updatedElement = await page.$('foo');18  console.log(await updatedElement.textContent());19});Using AI Code Generation
1const { updateOpaqueIdentifier } = require('playwright/lib/server/browserType');2const { chromium } = require('playwright');3(async () => {4  const browser = await chromium.launch();5  const context = await browser.newContext();6  const page = await context.newPage();7  const opaqueId = page._delegate._id;8  updateOpaqueIdentifier(opaqueId, 'newPageId');9  await page.screenshot({ path: 'example.png' });10  await browser.close();11})();12const { updateOpaqueIdentifier } = require('playwright/lib/server/browserType');13const { chromium } = require('playwright');14(async () => {15  const browser = await chromium.launch();16  const context = await browser.newContext();17  const page = await context.newPage();18  const opaqueId = page._delegate._id;19  updateOpaqueIdentifier(opaqueId, 'newPageId');20  await page.screenshot({ path: 'example.png' });21  await browser.close();22})();23const { updateOpaqueIdentifier } = require('playwright/lib/server/browserType');24const { chromium } = require('playwright');25(async () => {26  const browser = await chromium.launch();27  const context = await browser.newContext();28  const page = await context.newPage();29  const opaqueId = page._delegate._id;30  updateOpaqueIdentifier(opaqueId, 'newPageId');31  await page.screenshot({ path: 'example.png' });32  await browser.close();33})();34const { updateOpaqueIdentifier } = require('playwright/lib/server/browserType');35const { chromium } = require('playwright');36(async () => {37  const browser = await chromium.launch();38  const context = await browser.newContext();39  const page = await context.newPage();40  const opaqueId = page._delegate._id;41  updateOpaqueIdentifier(opaqueId, 'newPageId');42  await page.screenshot({ path: 'example.png' });Using AI Code Generation
1const { chromium } = require('playwright');2const { updateOpaqueIdentifier } = require('playwright/lib/internal/inspectorInstrumentation');3(async () => {4  const browser = await chromium.launch({headless: false});5  const page = await browser.newPage();6  updateOpaqueIdentifier(page, 'newOpaqueId');7  await page.close();8  await browser.close();9})();10const playwright = require('playwright');11const { updateOpaqueIdentifier } = require('playwright/lib/internal/inspectorInstrumentation');12(async () => {13  const browser = await playwright.chromium.launch({headless: false});14  const page = await browser.newPage();15  updateOpaqueIdentifier(page, 'newOpaqueId');16  await page.close();17  await browser.close();18})();Using AI Code Generation
1const { updateOpaqueIdentifier } = require('playwright/lib/server/supplements/recorder/recorderApp');2const { updateOpaqueIdentifier } = require('playwright/lib/server/supplements/recorder/recorderApp');3const { updateOpaqueIdentifier } = require('playwright/lib/server/supplements/recorder/recorderApp');4const { updateOpaqueIdentifier } = require('playwright/lib/server/supplements/recorder/recorderApp');5const { updateOpaqueIdentifier } = require('playwright/lib/server/supplements/recorder/recorderApp');6const { updateOpaqueIdentifier } = require('playwright/lib/server/supplements/recorder/recorderApp');7const { updateOpaqueIdentifier } = require('playwright/lib/server/supplements/recorder/recorderApp');8const { updateOpaqueIdentifier } = require('playwright/lib/server/supplements/recorder/recorderApp');9const { updateOpaqueIdentifier } = require('playwright/lib/server/supplements/recorder/recorderApp');10const { updateOpaqueIdentifier } = require('playwright/lib/server/supplements/recorder/recorderApp');11const { updateOpaqueIdentifier } = require('playwright/lib/server/supplements/recorder/recorderApp');12const { updateOpaqueIdentifier } = require('playwright/lib/server/supplements/recorder/recorderApp');13const { updateOpaqueIdentifier } = require('playwright/lib/server/supplements/recorder/recorderApp');14const { updateOpaqueIdentifier } = require('playwright/lib/server/supplements/recorder/recorderApp');Using AI Code Generation
1const { updateOpaqueIdentifier } = require('playwright/lib/client/transport');2(async () => {3  const browser = await chromium.launch();4  const page = await browser.newPage();5  await page.screenshot({ path: 'example.png' });6  updateOpaqueIdentifier(page, 'my-page-1');7  await browser.close();8})();9const { updateOpaqueIdentifier } = require('playwright/lib/client/transport');10(async () => {11  const browser = await chromium.launch();12  const page = await browser.newPage();13  await page.screenshot({ path: 'example.png' });14  updateOpaqueIdentifier(page, 'my-page-2');15  await browser.close();16})();17const { updateOpaqueIdentifier } = require('playwright/lib/client/transport');18(async () => {19  const browser = await chromium.launch();20  const page = await browser.newPage();21  await page.screenshot({ path: 'example.png' });22  updateOpaqueIdentifier(page, 'my-page-3');23  await browser.close();24})();25const { updateOpaqueIdentifier } = require('playwright/lib/client/transport');26(async () => {27  const browser = await chromium.launch();28  const page = await browser.newPage();29  await page.screenshot({ path: 'example.png' });30  updateOpaqueIdentifier(page, 'my-page-4');31  await browser.close();32})();33const { updateOpaqueIdentifier } = require('playwright/lib/client/transport');34(async () => {35  const browser = await chromium.launch();36  const page = await browser.newPage();Using AI Code Generation
1const playwright = require('playwright');2const internal = require('playwright/lib/server/supplements/recorder/recorderSupplement').RecorderSupplement;3(async () => {4    const browser = await playwright.chromium.launch({ headless: false });5    const context = await browser.newContext();6    const page = await context.newPage();7    console.log('Page URL: ' + page.url());8    await internal.updateOpaqueIdentifier(page, 'newPage');9    console.log('Page URL: ' + page.url());10    await page.close();11    await context.close();12    await browser.close();13})();14const playwright = require('playwright');15const internal = require('playwright/lib/server/supplements/recorder/recorderSupplement').RecorderSupplement;16(async () => {17    const browser = await playwright.chromium.launch({ headless: false });18    const context = await browser.newContext();19    const page = await context.newPage();20    console.log('Page URL: ' + page.url());21    await internal.updateOpaqueIdentifier(page, 'newPage');22    console.log('Page URL: ' + page.url());23    await page.close();24    await context.close();25    await browser.close();26})();Using AI Code Generation
1const {chromium} = require('playwright');2const { updateOpaqueIdentifier } = require('playwright/lib/internal/transport');3(async () => {4  const browser = await chromium.launch();5  const context = await browser.newContext();6  const page = await context.newPage();7  await updateOpaqueIdentifier(page, 'opaqueId');8  await page.screenshot({ path: `example.png` });9  await browser.close();10})();11const {chromium} = require('playwright');12const { updateOpaqueIdentifier } = require('playwright/lib/internal/transport');13describe('Playwright Test', () => {14  it('should test the page', async () => {15    const browser = await chromium.launch();16    const context = await browser.newContext();17    const page = await context.newPage();18    await updateOpaqueIdentifier(page, 'opaqueId');19    await page.screenshot({ path: `example.png` });20    await browser.close();21  });22});23const {chromium} = require('playwright');24const { setDefaultTimeout } = require('playwright/lib/internal/transport');25(async () => {26  const browser = await chromium.launch();27  const context = await browser.newContext();28  const page = await context.newPage();29  await setDefaultTimeout(page, 30000);30  await page.screenshot({ path: `example.png` });31  await browser.close();32})();33const {chromium} = require('playwright');34const { setDefaultTimeout } = require('playwright/lib/internal/transport');35describe('Playwright Test', () => {36  it('should test the page', async () => {37    const browser = await chromium.launch();38    const context = await browser.newContext();39    const page = await context.newPage();40    await setDefaultTimeout(page, 30000);Using AI Code Generation
1const { updateOpaqueIdentifier } = require('playwright/lib/server/browserContext');2updateOpaqueIdentifier('myopaqueidentifier');3The API is exposed as a method of the playwright module. You can import it using the following code:4const { updateOpaqueIdentifier } = require('playwright/lib/server/browserContext');5updateOpaqueIdentifier(opaqueIdentifier: string)6const { chromium } = require('playwright');7(async () => {8  const browser = await chromium.launch();9  const context = await browser.newContext();10  const page = await context.newPage();11  console.log(page.opaqueIdentifier());12  await browser.close();13})();LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!
