How to establish basic loading state using html, javascript and Reactjs hooks?
Require:
1) React function component.
2) It should just return the loading text: “Loading”.
3) The display increments (+1) every second to the point at which the loaded text ends.
For example: Loading.
-1s- Loading..
-1s- Loading...
-1s- Loading
method:
Identify static elements. Then add dynamics (state, hooks, etc.). according to Thinking in React document.
Static element implementation:
1) Create a functional component that returns “Loading”.
const Loading = () => {
const loadingText = "Loading";
return (
{loadingText}
);
};
export default Loading;
dynamics:
1) The number of points represents the status of the component. Therefore, define state variables using useState
.
const [dots, setDots] = useState(1);
and add the dot after loading the text
{".".repeat(dots)}
2) The status changes automatically every second. window.setInterval
can perform this task. Leave the callback function empty for now.
window.setInterval(() => {
// Logic to increment dots
}, 1000);
3) Create a useEffect
A hook that only runs once after the initial render.
useEffect(() => {
window.setInterval(() => {
// Logic to increment dots
}, 1000);
}, []);
So far the app only says “Loading”.
Pause for a moment and think about the logic. window.setInterval
callback function.
Obvious solution:
setDots((dots + 1) % 4);
However, this is wrong. This component will only come from
“Loading.” -1s- “Loading..”. Then it gets stuck.
reason: this useEffect's
Callback fn fires on the initial state of the point (1). Any updates to point variables will not affect useEffect's
callback function.
Catch 1: It makes no sense to include dots in useEffect’s dependency array. Because then it calls window.setInterval
Each time the point status is updated. (can be used window.setTimeout
instead. but why?
Catch 2:The point state of the loading component should depend on useEffect
and window.setInterval
. However, directly in useEffect
Make useEffect dependent on it.
Before taking the next step, consider closure.
Revision method
definition useEffect's callback's own dots state (say effectDots
). this window.setInterval
The callback function is added effectDots
And set the loading component dots
state.
(The key is to change the dependencies setInterval -> component's dots state
arrive component's dots state -> setInterval
. )
Revision of callback function useEffect
and window.setInterval
with local country effectDots
:
useEffect(() => {
let effectDots = 1;
window.setInterval(() => {
// increment, modulo 4
// set the Loading component's state
setDots(effectDots++ % 4);
}, 1000);
}, []);