Intensive reading of "use what changed source code"

1 Introduction

When using React Hooks, there are often too many executions or even a dead cycle. We can use use-what-changed Do dependency analysis to find out which variable reference has been changing.

According to an example, for example, you try to render the Function component inside the Class component, which is written as follows:

class Parent extends React.PureComponent {
  render() {
    return <Child style={{ color: "red" }} />;
  }
}

The subcomponent is written as follows:

const Child = ({ style }) => {
  const [localStyle, setLocalStyle] = useState();

  useEffect(() => {
    setLocalStyle(style);
  }, [style]);

  return null;
};

Congratulations, then, for writing the simplest cycle. In this scenario, we intend to use useEffect to props.style Synchronize to the local state localStyle, but executing setLocalStyle will cause the current component to re render. Because of the writing method of the parent style = {{color: "red"}}, you get it every time props.style The references will change, so the useEffect callback is triggered again, and then executed again setLocalStyle triggers a loop.

Just printing out the value can't see the change, and the change of reference is very hidden. In order to judge whether the change needs to store the last value for comparison, it's very troublesome. Use what changed is to solve this problem.

2 Intensive Reading

Use what changed is used as follows:

function App() {
  useWhatChanged([a, b, c, d]); // debugs the below useEffect

  React.useEffect(() => {
    // console.log("some thing changed , need to figure out")
  }, [a, b, c, d]);
}

Pass in parameters like dependency arrays. Refresh the page to see whether the reference or value changes on the console. If it changes, the corresponding line will display ✅ And print the last value and the current value:

The first step is to store the value of the last dependency, using useRef to implement:

function useWhatChanged(dependency?: any[]) {
  const dependencyRef = React.useRef(dependency);
}

Then, use use effect to compare the references of dependency and dependencyRef to find the change item:

React.useEffect(() => {
  let changed = false;
  const whatChanged = dependency
    ? dependency.reduce((acc, dep, index) => {
        if (dependencyRef.current && dep !== dependencyRef.current[index]) {
          changed = true;

          const oldValue = dependencyRef.current[index];
          dependencyRef.current[index] = dep;
          acc[`"✅" ${index}`] = {
            "Old Value": getPrintableInfo(oldValue),
            "New Value": getPrintableInfo(dep),
          };

          return acc;
        }

        acc[`"⏺" ${index}`] = {
          "Old Value": getPrintableInfo(dep),
          "New Value": getPrintableInfo(dep),
        };

        return acc;
      }, {})
    : {};

  if (isDevelopment) {
    console.table(whatChanged);
  }
}, [dependency]);
  1. Compare the deps reference directly. If you don't want to wait, set changed to true.
  2. In debugging mode, use console.table Print out the form.
  3. The dependency is dependency, and whatChanged is printed only when the dependency changes.

The above is the core logic of the source code. Of course, we can also simplify the output, print the table only when there is a reference change, otherwise only output simple Log information:

if (isDevelopment) {
  if (changed) {
    console.table(whatChanged);
  } else {
    console.log(whatChanged);
  }
}

babel plug in

Finally, use what changed also provides babel plug-in, which can print useMemo, useEffect and other dependent change information only through comments. babel is configured as follows:

{
  "plugins": [
    [
      "@simbathesailor/babel-plugin-use-what-changed",
      {
        "active": process.env.NODE_ENV === "development" // boolean
      }
    ]
  ]
}

The usage is simplified as follows:

// uwc-debug
React.useEffect(() => {
  // console.log("some thing changed , need to figure out")
}, [a, b, c, d]);

The deps array of Hooks is directly converted to the input parameter of use what changed.

3 Summary

use-what-changed The debugging method of Hooks dependent changes is added. For the re rendering analysis of React components, the React Dev Tool can be used, which can be referred to Intensive reading of React performance debugging.

What other practical Hooks debugging tools are available? Welcome to share.

Discussion address: Intensive reading of "use what changed source code" · issue ෤ DT Fe / weekly

If you want to participate in the discussion, please click here , new theme every week, released on weekend or Monday. Front end intensive reading - help you to select reliable content.

Focus on front-end intensive reading WeChat official account

Copyright notice: Free Reprint - non commercial - non derivative - keep signature( Creative sharing 3.0 License)

This article uses mdnice Typesetting

Keywords: Javascript React

Added by okyejr on Mon, 15 Jun 2020 05:25:59 +0300