Sometimes you need to dispatch a thunk or an action right away, without waiting for the user to initiate an event. For example, you might need to pull down data from a web service to populate your local Redux store. Your first instinct might be to dispatch a thunk right inside your App
component:
function App() {
const dispatch = useDispatch();
dispatch(downloadName());
return (
<div class="App">
{/* ... */}
</div>
);
}
The drawback to this approach is that the thunk will be dispatch not just when the app first loads, but also every time App
re-renders. Since any state change will cause a re-render, you'll be dispatching a lot of thunks. You may want that sometimes, but not for a startup routine. A better approach is to use React's useEffect
function. You pass useEffect
a function that produces some side effect, like scheduling a task with setTimeout
or dispatching a thunk:
import {useEffect} from 'react';
function App() {
const dispatch = useDispatch();
useEffect(() => {
dispatch(downloadName());
});
return (
<div class="App">
{/* ... */}
</div>
);
}
When you pass only a single parameter to useEffect
the function is executed on every render. If you only want it to run once, you pass an empty array as the second parameter:
useEffect(() => {
dispatch(downloadName());
}, []);
This second parameter is an array of the effect function's dependencies. Whenever any of the dependencies changes, the effect function is called. An empty array means that it has no dependencies. It will be run once when the app first loads and never again.
However, in this case, the React tooling complains that your effect function does have a dependency. It references dispatch
. You add it to the list of dependencies:
useEffect(() => {
dispatch(downloadName());
}, [dispatch]);
The warning goes away. Since Redux's dispatch
function never changes, your effect function only runs once throughout the lifetime of your app.