In this practice, you will dispatch the thunks returned from the thunk action creators you wrote in the previous practice.
Clone the starter repo accessible from the Download Project
button at the
bottom of this page.
- Install dependencies
- Create a .env file based on the example with proper settings for your local environment
- Run
npm install
in the backend directory to install dependencies. - Create a database user with the same name and password as found in your
.env file with
CREATEDB
privileges - Run
npm run db:setup
to set up the database. - Run
npm start
to start the backend server.
In a different terminal, cd
into the frontend directory of the starter.
- Run
npm install
in the frontend directory. - Run
npm start
in the frontend directory to start the server.- Note that the package.json now defines a proxy of
http://localhost:5000
. This will effectively forward any unrecognized requests to the port (5000
) on which your backend is listening.
- Note that the package.json now defines a proxy of
In the previous practice, you wrote thunk action creators, i.e., functions that
returned a thunk action. In this practice, you will dispatch
those thunk
actions.
In the frontend/src/components/ArticleList/index.js file, you will update
the component from dispatch
-ing the action returned by the regular action
creator--i.e., the old loadArticles()
--to dispatch
-ing the thunk action
returned from the thunk action creator. Change the import
statement near the
top of the file to import the thunk action creator. Update the dispatch
call
inside the useEffect
hook to dispatch
the returned thunk action from the
fetchArticles
thunk action creator.
You should dispatch
your thunk actions the same way you dispatch
-ed the
actions returned from your action creators, using the same dispatch
made
available in your application through the useDispatch
hook.
Once you finish, your code should look something like this:
import { fetchArticles } from '../../store/articleReducer';
const ArticleList = () => {
const dispatch = useDispatch();
const articles = useSelector(state=>state.articleState.entries);
useEffect(() => {
dispatch(fetchArticles());
}, [dispatch]);
// ...
};
You ended the last practice with a broken app because you were no longer loading the articles. Now that you are fetching the articles, test your code in the browser again. You should see the "Article List" displaying the various titles once again. Yea!
Now click on one of the titles. You will probably see a blank screen with the
DevTools console shouting at you because SingleArticle
is trying to access
inside of undefined
. In short, SingleArticle
can't find the article it
is supposed to display. Fix this problem in the SingleArticle
component.
Hint: the database assigns integer
id
s rather than the stringid
s assigned bynanoid
.
Once you get SingleArticle
to render again, refresh the page. Oh no! It's
(likely) broken again. Check the state in the Redux DevTools:
articleState.entries
should be empty. The refresh clears the Redux store, but
why doesn't the app just re-fetch the articles?
Take a look in ArticleList/index.js. Notice that you fetch the articles in a
useEffect
, and a useEffect
always runs after a render. In other words,
your app will always render at least once before it fetches the articles. It's
this first render that's the problem: there are no articles loaded for
SingleArticle
to grab. To fix this, use some kind of conditional to make sure
that SingleArticle
doesn't try to render singleArticle
--note the lowercase
's'--if there is no article to display. (There are several ways this could be
done; just pick one.)
Once SingleArticle
makes it through the first render, the useEffect
will
run, fetch the articles, and load them into the Redux store. This updating of
the store will then trigger a re-render in which SingleArticle
should be able
to find and display the specified article (assuming it was a valid article
request to begin with). All of this typically happens so quickly that it is hard
for the human eye to even notice that more than one render occurs!
Now it's your turn! Update the ArticleInput
component found in the
frontend/src/component/ArticleInput/index.js file to use the writeArticle
thunk action creator when the user submits the form to create a new article.
Tip: The database will now assign the new article an
id
, so you will no longer neednanoid
.
Note that you will want to await
the result of your dispatch
and only reset
the form if the article was successfully entered into the database. You can only
await
inside an async
function, however, so you will also need to re-define
handleSubmit
accordingly:
const handleSubmit = async (e) => {
// ...
}
Congratulations! In this practice you have learned how to
dispatch
thunk actions from within your React components- Debug some of the issues that commonly arise when using thunks