1 the introduction
Use use-what-changed dependency analysis to find out which variable reference is changing all the time when using React Hooks.
For example, if you try to render a Function component inside a Class component, the Class component would say:
class Parent extends React.PureComponent {
render() {
return <Child style={{ color: "red}} "/ >; }}Copy the code
The child component is written like this:
const Child = ({ style }) = > {
const [localStyle, setLocalStyle] = useState();
useEffect((a)= > {
setLocalStyle(style);
}, [style]);
return null;
};
Copy the code
So congratulations, you’ve written the simplest of all endless loops. In this scenario, we intended to use useEffect to synchronize props. Style to the local state localStyle, but executing setLocalStyle will cause the current component to be re-rendered, because the parent style={{color: The “red”}} is written so that the props. Style reference is changed each time you re-render it, so the useEffect callback is executed again, and setLocalStyle is executed again to trigger an infinite loop.
The use-what-changed is used to solve this problem because the change of the reference is very subtle and you have to store the previous value for comparison in order to determine whether it has changed.
2. Intensive reading
Use-what-changed Can be used as follows:
function App() {
useWhatChanged([a, b, c, d]); // debugs the below useEffect
React.useEffect((a)= > {
// console.log("some thing changed , need to figure out")
}, [a, b, c, d]);
}
Copy the code
Pass the parameters as if they were dependent arrays and refresh the page to see if the reference or value has changed in the console. If it has, the corresponding line displays ✅ and prints out the last value and the current value:
The first step is to store the value of the previous dependency, using useRef:
function useWhatChanged(dependency? : any[]) {
const dependencyRef = React.useRef(dependency);
}
Copy the code
Then useEffect to compare the reference of dependency and dependencyRef to find the change item:
React.useEffect((a)= > {
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]);
Copy the code
- Compare dePS references directly, if you don’t want to wait
changed
Set to true. - In debugging mode, use console.table to print the table.
- The dependency is dependency, and whatChanged is printed when the dependency changes.
This is the core logic of the source code, of course, we can also simplify the output, only when there is a reference change to print the table, otherwise just output simple Log information:
if (isDevelopment) {
if (changed) {
console.table(whatChanged);
} else {
console.log(whatChanged); }}Copy the code
Babel plug-in
Finally, use-What-changed also provides the Babel plug-in, which can print useMemo, useEffect, and other dependency change information only through annotations. Babel configuration is as follows:
{
"plugins": [["@simbathesailor/babel-plugin-use-what-changed",
{
"active": process.env.NODE_ENV === "development" // boolean}}]]Copy the code
The mode of use is simplified as:
// uwc-debug
React.useEffect((a)= > {
// console.log("some thing changed , need to figure out")
}, [a, b, c, d]);
Copy the code
Convert the deps array of Hooks directly to use-what-changed inputs.
3 summary
The React Dev Tool is available for re-rendering analysis of the React component. See The Detailed review of React Performance Debugging.
What are the Hooks debugging tools that are useful? Welcome to share.
The discussion address is: intensive reading “use-What-changed source code” · Issue #256 · dt-fe/weekly
If you’d like to participate in the discussion, pleaseClick here to, with a new theme every week, released on weekends or Mondays. Front end Intensive Reading – Helps you filter the right content.
Pay attention to the front end of intensive reading wechat public account
Copyright Notice: Freely reproduced – Non-commercial – Non-derivative – Remain signed (Creative Commons 3.0 License)