Building an EdTech Web app with React, Redux-Toolkit, + Rails backend

Building an EdTech Web app with React, Redux-Toolkit, + Rails backend

Notable practice: Before you start coding take a moment to think about how can I best represent this problem?

Ā·

4 min read

Greetings and Happy Spring! šŸŒ¾

I reached the final module in my Flatiron Bootcamp journey and I could not be more proud of myself. Prior to flatiron I worked on several startups that has given me hands on exposure to the full stack of an app at production. Iā€™m experiencing many overwhelming emotions and thoughts on my growth in my technical aptitude this year! Getting this far in my bootcamp helps me affirm that even though I completed the modules my journey as a software engineer has only just begun. Out of the gate Iā€™m looking to connect with as many developers as possible to accelerate my learning goals. Especially, but not limited to, the backend of the tech stack.

<Soft launch šŸš€

Enter my final project, Abena DMS, an app to support teachers working with young students in the classroom.

Coming late ā€˜22. ReactJS was a real breath of fresh air compared to VanillaJS in terms of manipulation of the DOM, handling AJAX requests, and being introduced to state management.

/>

I saw the opportunity to challenge myself and explore using Redux Toolkit instead of plain olā€™ redux for this project. After going through the lecture and realizing the limitations of Redux:

  • Reason 1: A over-complex setup of the store for example - Originally, I set up my actions, reducers, and constants separately.

    • That is all replaced using Reduxā€™s createSlice API which is a helper method or high order function that generates a store ā€œsliceā€. How it works is it takes the name of slice, initial state + reducer function to return reducer, action types, etcā€¦ that corresponds to state.

example from createSlice documentation:

import { createSlice } from '@reduxjs/toolkit'

const initialState = { value: 0 }

const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    increment(state) {
      state.value++
    },
    decrement(state) {
      state.value--
    },
    incrementByAmount(state, action) {
      state.value += action.payload
    },
  },
})


export const { increment, decrement, incrementByAmount } = counterSlice.actions
export default counterSlice.reducer
  • Reason 2: requirements of too much boilerplate code

  • Reason 3: I found myself adding various packages to my original redux version of the project. Then I started to get flashbacks of using only vanillaJS.

How did you get data to show up in the client using Toolkit?

As you may know, at the root Redux is synchronous, so I needed to add middleware like Redux-Thunk or Saga to help us with the asynchronous bit. With Redux-Toolkit, we get Thunk already integrated as a dependency.

Enter createAsyncThunk

createAsyncThunk is a function that accepts a Redux action type string and a callback function that should return a promise. It generates promise lifecycle action types based on the action type prefix that you pass in, and returns a thunk action creator that will run the promise callback and dispatch the lifecycle actions based on the returned promise.

This built-in function accepts three parameters:

  1. Type: with AbenaDMS it was ā€œstrategies/getStrategiesā€

  2. payloadCreator: a callback function the first argument passed to the callback, the second param is the thunkAPI that has some pretty nifty error handling features for example a try-catch statement in your ajax requests.

  3. options: is an object with two props, the condition is a callback which returns a bool that can be used to skip execution.

With plain React and Class components using Redux we manage lifecycle components with ComponentDidMount, WillMount, etcā€¦ with Redux toolkit and the createAsyncThunk API lifecycle actions are BUILT-IN.

The three lifecycle actions are: pending: before the callback is called in the payloadCreator

fulfilled: on successful executions

rejected: in case of an error

I also integrated framer motion for some light animations into my project but that is a topic for another post.

With these tools in place, it's far easier to dispatch actions with minimal code and provides some really powerful tools for state management. I'm looking forward to keeping following the engineering rabbit hole šŸ•³ and navigating a teacher-student attitude. Asking for constructive feedback as well as giving feedback to others to support other devs.

Special thank you to my cohort leads for being there for me, my friends, and my family supporting me while I learn in public.

As always here are some tunes to work to, I'm hooked to this Ampiano sound:

soundcloud.app.goo.gl/AfEEaYXNZMKzzBxCA

Follow me on my SWE journey and drop any resources to what you wish you knew if you were starting over this morning. I'm currently reading: Software Engineering at Google, Lessons learned over Time

Ā