Deep Dive React 3 React Hooks

2022-08-16  本文已影响0人  吴摩西

React Hooks allow us to use React features without writing a class

A lot of questions surrounding react hooks

const ReactX = (() => {
  let hooks = [];
  let index = 0;
  const useState = (initialValue) => {
    const localIndex = index;
    index++;
    if (hooks[localIndex] === undefined) {
      hooks[localIndex] = initialValue;
    }
    const setterFunction = (newValue) => (hooks[localIndex] = newValue);
    return [hooks[localIndex], setterFunction];
  };
  const resetIndex = () => {
    index = 0;
  };

  const useEffect = (callback, dependencyArray) => {
    let hasChanged = true;
    const oldDependencies = hooks[index];
    if (oldDependencies) {
      hasChanged = false;
      dependencyArray.forEach((dependency, index) => {
        const oldDependency = oldDependencies[index];
        const areTheSame = Object.is(dependency, oldDependency);
        if (!areTheSame) {
          hasChanged = true;
        }
      });
    }
    if (hasChanged) {
      callback();
    }
    hooks[index] = dependencyArray;
    index ++;
  };

  return {
    useState,
    useEffect,
    resetIndex
  };
})();

const { useState, useEffect, resetIndex } = ReactX;
const Component = () => {
  const [counterValue, setCounterValue] = useState(1);
  console.log(counterValue);
  useEffect(() => {
    console.log('useEffect');
  }, []);
  if (counterValue !== 2) {
    setCounterValue(2);
  }
};
Component();
resetIndex();
Component();

Composition = hooks don't conflict with each other
Debugging = bugs should be easy to find

const Button = ({ color }) => {
  // it will bail out re-render unless callback returns true
  useBailout(previousColor => previousColor !== color, color);
  return (<button className={`${color}-button`}>Button</button>)
}

How can useState() be a part of rendering?

// inside React
const React = {
  // ...
  __currentDispatcher: null,
  useState(initialState) {
    return React.__currentDispatcher.useState(initialState);
  }
};
// inside React DOM
const previousDispatcher = React.__currentDispatcher;
React.__currentDispatcher = ReactDOMDispatcher;
let result;
try {
  result = Component(props);
} finally {
  React.__currentDispatcher = previousDispatcher;
}
上一篇下一篇

猜你喜欢

热点阅读