akoven / Thunk_Redux

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Practice: Thunk Action Creators

In this practice, you will write thunk action creators that you will use later with Redux.

Setup

Clone the starter repo accessible from the Download Project button at the bottom of this page.

  1. Install dependencies
  2. Create a .env file based on the example with proper settings for your local environment
  3. Run npm install in the backend directory to install dependencies.
  4. Create a database user with the same name and password as found in your .env file with CREATEDB privileges
  5. Run npm run db:setup to set up the database.
  6. Run npm start to start the backend server.

In a different terminal, cd into the frontend directory of the starter.

  1. Run npm install in the frontend directory.
  2. 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.

Installing thunk middleware

Action creators are functions that create and return an action, which is just a regular JavaScript object. Thunk action creators are functions that return a thunk action, which is a function instead of an object.

Accordingly, for your thunk actions and thunk action creators to work correctly, you first need to install thunk middleware that will intercept every action and check to see whether or not it is a function. If the action is a thunk action / function, the middleware will invoke it; if the action is a regular JS object, the middleware will pass it on to the reducers.

To install the thunk middleware, open the index.js file in your frontend/src/store directory. At the top of the file import thunk from 'redux-thunk'. (It is a default export.) Next, add thunk as the first argument to applyMiddleware when you are setting up the enhancer. The code currently does not set up the enhancer in production mode, but you need the thunk middleware in place even in production. Accordingly, after the if-clause checking whether or not process.env.NODE_ENV !== production, add an else that sets the enhancer equal to applyMiddleware(thunk). The relevant portion of the file should now look something like this:

if (process.env.NODE_ENV !== 'production') {
  const logger = require('redux-logger').default;
  const composeEnhancers =
    typeof window === 'object' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({ trace: true }) : compose;
  enhancer = composeEnhancers(applyMiddleware(thunk, logger));
} else {
  enhancer = applyMiddleware(thunk);
}

Your thunk middleware is now installed and ready to go!

Thunk action creators

Now it's time to write some thunk actions and thunk action creators. A thunk action--or simply thunk--accepts the dispatch and getState methods available on the store and can dispatch another action after potentially doing some asynchronous logic.

Because a thunk action creator is just a function that returns a thunk (i.e., a function) that takes in dispatch and getState as parameters, most of the time, you'll see it structured like this:

const thunkActionCreator = () => dispatch => {
  // Thunk logic here
};

Note: The getState parameter is often omitted when it is not needed.

This translates to function declaration syntax like so:

function thunkActionCreator() {
  return function thunk(dispatch) {
    // Thunk logic here
  };
}

fetchArticles

In the frontend/src/store/articleReducer.js file, write a fetchArticles thunk action creator that uses the Fetch API to request articles at the relative path /api/articles. dispatch the returned action from the loadArticles action creator. You will want to rewrite the definition of the loadArticles function so that it can accept an articles argument, which you will get by calling the asynchronous .json() method on the response you got back from the fetch call. (You no longer need to import articles from data/data.json!) Go ahead and export the function.

Your thunk action creator might look like this:

export const fetchArticles = () => async dispatch => {
  const response = await fetch('/api/articles');
  const articles = await response.json();
  dispatch(loadArticles(articles));
};

Remember to update the definition of the loadArticles function.

Note: Updating the loadArticles function will break your app because ArticleList--as currently configured--will no longer be able to get the list of articles to display. Do not worry about this now; you will fix it in the next practice!

Time to test! Since the app is not functioning at the moment, you will need to test your thunk action creator by putting it on the window. In your root index.js, change the import from './store/articleReducer' to import everything from the file as articleActions. Then add articleActions to the window. It should look like this:

// frontend/src/index.js

import * as articleActions from './store/articleReducer';
// ...
if (process.env.NODE_ENV !== 'production') {
  window.store = store;
  window.articleActions = articleActions;
}

In the DevTools console of your browser, run this command:

store.dispatch(articleActions.fetchArticles())

Check the logger result to make sure that articleState.entries has updated!

writeArticle

Now it's your turn! Write a writeArticle thunk action creator in the frontend/src/store/articleReducer.js file that takes in a payload and makes a POST request to /api/articles. To do this, you should pass an object specifying the method, headers--this should point to another object where 'Content-Type' is set to 'application/json'--and body (properly stringify-ed) as the second argument to fetch.

If the request is successful, call dispatch on the return value of addArticle invoked with the new article from the response. The action creator should also return the newly-created article.

Hint: Remember to use .json() to parse your received data before dispatching.

To test your writeArticle, run the following commands in your browser console:

let article = {title: 'b2', body: 'sunset', imageUrl: 'https://fancycrave.com/wp-content/uploads/2019/02/Stunning-Orange-and-Purple-Sunset-above-the-Sea-in-Thailand.jpg'}
store.dispatch(articleActions.writeArticle(article))

Once again, the logger results should confirm whether or not your article was created and added to the Redux state.

In the next practice, you will learn how to dispatch these thunk action creators from within your code.

What you have learned

Congratulations! In this practice you have learned how to

  1. Write thunk action creators

About


Languages

Language:JavaScript 85.8%Language:CSS 11.0%Language:HTML 2.5%Language:Shell 0.7%