Reloading a Document (and Preserving Query String Parameters) Using Only HTML
<a href="">Reload</a>
React Hooks and Javascript Closures
Everything in useEffect, useCallback hooks is a closure.
const HeavyComponentMemo = React.memo(HeavyComponent);
const Form = () => {
const [value, setValue] = useState();
const onClick = () => {
// submit our form data here
console.log(value);
};
return (
<>
<input
type="text"
value={value}
onChange={(e) => setValue(e.target.value)}
/>
<HeavyComponentMemo
title="Welcome to the form"
onClick={onClick}
/>
</>
);
};
onClick changed between re-renders. We want the HeavyComponentMemo component is stable between re-renders.
const HeavyComponentMemo = React.memo(
HeavyComponent,
(before, after) => {
return before.title === after.title;
},
);
const Form = () => {
const [value, setValue] = useState();
const onClick = () => {
// submit our form data here
console.log(value);
};
return (
<>
<input
type="text"
value={value}
onChange={(e) => setValue(e.target.value)}
/>
<HeavyComponentMemo
title="Welcome to the form"
onClick={onClick}
/>
</>
);
};
The value that we log in onClick is undefined, value‘s initial value. onClick changed between re-renders, but HeavyComponentMemo not, it still use the initial onClick.
We can append before.onClick === after.onClick in the React.memo comparison function, but we go back to the first version of the code.
We can wrap our onClick in useCallback, but useCallback depends on value, the value will change with every keystroke, the result still likes the first version of the code.
The key is to make onClick stable, and still can access the latest value. The following code do this:
const Form = () => {
const [value, setValue] = useState();
const ref = useRef();
useEffect(() => {
ref.current = () => {
// will be latest
console.log(value);
};
});
const onClick = useCallback(() => {
// will be latest
ref.current?.();
}, []);
return (
<>
<input
type="text"
value={value}
onChange={(e) => setValue(e.target.value)}
/>
<HeavyComponentMemo
title="Welcome closures"
onClick={onClick}
/>
</>
);
};
In ref.current?.(), ?. is the optional chaining operator, if ref.current is undefined or null, it will return undefined, not throwing an error.
The Mad Magazine Fold-In Effect in CSS
Amazing fold-in effect.