EN / PT

Welcome!

I am the one that will deliver your software

My name is Marcelo L. Lotufo, I have a degree in Computer Sciences from UFSCar (2018) and I have been developing web apps since 2012. I have worked in plenty of apps for different fields: web conference apps, chatbot platform, games, general web systems and pages.

Nowadays I am ahead of Lotuz , a software development agency for the web with international clientes, where we use agile methodology to deliver software quickly, on point and with quality.

Redux Thunk Utils

05/30/2019

This is a piece of code that was usefull for me while I was using redux and redux-thunk@1.x Some people found it usefull when I showed, so I am sharing it here.

It is basically a shortcut for writing actions and async api api requests/actions.



// Action shortcut
export function makeActionCreator(type, ...argNames) {
  let action = function (...args) {
    let action = { type }
    argNames.forEach((arg, index) => {
      action[argNames[index]] = args[index]
    })
    return action
  }

  return {
    action,
    type,
  }
}

// Usage
export const ENTER_CHAT_ROOM = makeActionCreator("ENTER_CHAT_ROOM", "room")



With our action generator utility, we further extend it for redux-thunk usage.

A common pattern arised most of the times I used thunk, so I abstracted it into a function. This way I had to write less code, but if needed the action could be further extended by chaining 'thens' and 'catchs' on the returning promise.



export function asyncCreator(api, actionName, resourceName) {
  let actionNames = ["REQUEST", "SUCCESS", "FAILURE"].map(
    stage => actionName + "_" + stage
  )
  let request = makeActionCreator(actionNames[0], "parameters").action
  let success = makeActionCreator(actionNames[1], resourceName).action
  let failure = makeActionCreator(actionNames[2], "error").action

  let action = function (...parameters) {
    return function (dispatch) {
      dispatch(request(...parameters))

      return api(...parameters)
        .then(function (response) {
          dispatch(success(response.data))
        })
        .catch(function (error) {
          dispatch(failure(error))
          throw error
        })
    }
  }

  return {
    REQUEST: actionNames[0],
    SUCCESS: actionNames[1],
    FAILURE: actionNames[2],
    request,
    success,
    failure,
    action,
  }
}

// actions.js - Usage

const fetchUsersApi = fetch("/users")

export const fetchUsers = asyncCreator(fetchUsersApi, "FETCH_USERS", "users")

// reducer.js

import { combineReducers } from "redux"
import fetchUsers from "./actions"

function loading(state = false, action) {
  switch (action.type) {
    case fetchUsers.REQUEST:
      return true
    case fetchUsers.SUCCESS:
    case fetchUsers.FAILURE:
      return false
    default:
      return state
  }
}

function error(state = "", action) {
  switch (action.type) {
    case fetchUsers.FAILURE:
      return action.error
    default:
      return state
  }
}

function users(state = [], action) {
  switch (action.type) {
    case fetchUsers.SUCCESS:
      return action.users
    default:
      return state
  }
}

export default combineReducers({
  loading,
  error,
  users,
})



These helper functions made my life with redux and redux-thunk much easier as long declaration files became short one.

Hope this can also help you out!