How to Save Files to a React Server With Thunks
You can find the working example for this lesson in the
code/04-redux/04.25-save-the-project-using-thunks
folder.
At this point we can save our drawings as .png
files. In this section, we'll make it possible to save the project to the server. It will be possible to load them later and continue drawing them.
We will learn how to perform side effect in Redux based applications using thunks.
Define the API module#
We are going to perform a server request. Let's define an API
module. Create a new file src/modules/strokes/api.ts
and define the newProject
function there:
xxxxxxxxxx
import { Stroke } from "../../utils/types"
​
export const newProject = (
name: string,
strokes: Stroke[],
image: string
) =>
fetch("http://localhost:4000/projects/new", {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify({
name,
strokes,
image
})
}).then((res) => res.json())
This function will perform a POST
request to our server and send the strokes list representing our project, project name and project thumbnail.
The fact that we send the whole strokes array to the backend will allow us to use undo
/redo
functionality immediately after we load the project.
Handle saving the project#
Saving the project is considered a side effect, and the official way to handle side-effects in Redux Toolkit are Thunks.
Think of them as a special kind of action creators. Instead of returning an object with type
and payload
, they return an async function that will perform the side-effect.
Open src/store.ts
and define the type for our thunk. To do this, you'll need to import ThunkAction
, Action
and RootState
types:
xxxxxxxxxx
import { configureStore, ThunkAction, Action } from "@reduxjs/toolkit"
// ...
import { RootState } from "./utils/types"
// ...
export type AppThunk = ThunkAction<
void,
RootState,
unknown,
Action<string>
>
Open the src/modules/strokes/slice.ts
and import the createAsyncThunk
method:
xxxxxxxxxx
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"
We'll also need to import the newProject
method frow the api
module:
xxxxxxxxxx
import { newProject } from "./api"
Now define the saveProject
thunk:
xxxxxxxxxx
type SaveProjectArg = {
projectName: string
thumbnail: string
}
// ...
export const saveProject = createAsyncThunk(
"SAVE_PROJECT",
async (
{ projectName, thumbnail }: SaveProjectArg,
{ getState }
) => {
try {
const response = await newProject(
projectName,
(getState() as RootState)?.strokes,
thumbnail
)
console.log(response)
} catch (err) {
console.log(err)
}
}
)
This lesson preview is part of the Fullstack React with TypeScript Masterclass course and can be unlocked immediately with a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to Fullstack React with TypeScript Masterclass with a single-time purchase.
