xxxxxxxxxx
function EffectsDemoTwoStatesWithDependeny() {
const [title, setTitle] = useState("default title");
const titleRef = useRef();
const [darkMode, setDarkMode] = useState(false);
useEffect(() => {
console.log("useEffect");
document.title = title;
}, [title]);
console.log("render");
const handleClick = () => setTitle(titleRef.current.value);
const handleCheckboxChange = () => setDarkMode((prev) => !prev);
return (
<div className={darkMode ? "view dark-mode" : "view"}>
<label htmlFor="darkMode">dark mode</label>
<input
name="darkMode"
type="checkbox"
checked={darkMode}
onChange={handleCheckboxChange}
/>
<input ref={titleRef} />
<button onClick={handleClick}>change title</button>
</div>
);
}
xxxxxxxxxx
const usePrevious = (value, initialValue) => {
const ref = useRef(initialValue);
useEffect(() => {
ref.current = value;
});
return ref.current;
};
xxxxxxxxxx
const useEffectDebugger = (effectHook, dependencies, dependencyNames = []) => {
const previousDeps = usePrevious(dependencies, []);
const changedDeps = dependencies.reduce((accum, dependency, index) => {
if (dependency !== previousDeps[index]) {
const keyName = dependencyNames[index] || index;
return {
accum,
[keyName]: {
before: previousDeps[index],
after: dependency
}
};
}
return accum;
}, {});
if (Object.keys(changedDeps).length) {
console.log('[use-effect-debugger] ', changedDeps);
}
useEffect(effectHook, dependencies);
};
xxxxxxxxxx
import { useEffect } from 'react';
function MyComponent() {
useEffect(() => {
// Runs ONCE after initial rendering
}, []);
}
xxxxxxxxxx
import { useEffect, useState } from 'react';
function MyComponent({ prop }) {
const [state, setState] = useState('');
useEffect(() => {
// Runs ONCE after initial rendering
// and after every rendering ONLY IF `prop` or `state` changes
}, [prop, state]);
}
xxxxxxxxxx
the [] at the end of the useEffect is where you declare your
data dependencies.
React wants to know when to run that effect again.
If You don't give it any data dependencies, it assumes any time
any hook changes that you should run the effect again.
You can instead provide which hooks to watch for changes for.
If we actually only want it to run once, on creation of the component,
and then to not run that effect again.
You can accomplish this only-run-on-creation by providing
an empty array [].