In react (before hooks) when we set state we could call a function after state had been set as such:
this.setState({}, () => {//Callback})
W
The useEffect hook can be used to invoke a function when some state change. If you pass it currentRange
in an array as second argument, the function will only be invoked when currentRange
change.
You can also create your own custom hook that uses the useRef hook to keep track of if it's the first time the effect is being run, so that you can skip the first invocation.
Example
const { useRef, useState, useEffect } = React;
function useEffectSkipFirst(fn, arr) {
const isFirst = useRef(true);
useEffect(() => {
if (isFirst.current) {
isFirst.current = false;
return;
}
return fn();
}, arr);
}
function App() {
const [currentRange, setCurrentRange] = useState("24h");
useEffectSkipFirst(
() => {
console.log("hi");
},
[currentRange]
);
return (
<button
onClick={() => setCurrentRange(Math.floor(Math.random() * 24) + 1 + "h")}
>
Change range ({currentRange})
</button>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>
You can use useEffect/useLayoutEffect to achieve this:
const SomeComponent = () => {
const [count, setCount] = React.useState(0)
React.useEffect(() => {
if (count > 1) {
document.title = 'Threshold of over 1 reached.';
} else {
document.title = 'No threshold reached.';
}
}, [count]);
return (
<div>
<p>{count}</p>
<button type="button" onClick={() => setCount(count + 1)}>
Increase
</button>
</div>
);
};
If you are looking for an out of the box solution, check out this custom hook that works like useState but accepts as second parameter a callback function:
import useStateWithCallback from 'use-state-with-callback';
const SomeOtherComponent = () => {
const [count, setCount] = useStateWithCallback(0, count => {
if (count > 1) {
document.title = 'Threshold of over 1 reached.';
} else {
document.title = 'No threshold reached.';
}
});
return (
<div>
<p>{count}</p>
<button type="button" onClick={() => setCount(count + 1)}>
Increase
</button>
</div>
);
};
It can be installed via npm install use-state-with-callback