Post to Sinatra with React JS/Ruby
Today we’ll discuss the process of making a POST request in React JS and persisting data to a Sinatra backend. Let’s get started!
First we’ll start with our server side, create a Movie
model and within our models
folder.

Next we’ll need to create a migration called CreateMovies
, which will create a Movies table.
bundle exec rake db:create_migration NAME=create_movies
We call the Active Record method create_table
, and assign datatypes to each of our table’s columns.

Make sure to run bundle exec rake db:migrate
. This will generate a database table for us, which we can view in our db/schema.rb
file, to ensure that our table was generated with the correct datatypes and columns.
Now let’s set up a couple of routes. The first route will be a GET route, which will retrieve all of our movies in our Movie table, in json
format. The second route will be a POST request for creating a new movie and adding it to the database. In your controllers/application_controller.rb
file, create these routes as follows:

Our get '/movies'
route is simple enough, it simply calls the ActiveRecord .all
method on our Movie model, then we call to_json
on movies
, which JSONifies the response for our frontend.
The post '/movies
route is a little more complicated. We iterate over our params
with the select
iterator method, passing k,v
as parameters (key and value). Then we hand it an array to check over, to see if any of these strings include the key we pass in. The array of strings is actually our movie columns from our database table, so in this method we’re allowing these strings to be passed as our movie parameters when we call our POST request from the frontend. These are the parameters that and sent in the body our request. Next we just call Movie.create(movie_params)
(another ActiveRecord method), and subsequently call to_json
on this newly created Movie object.
Now that we have our backend set up to receive requests, let’s move onto the frontend in React.

Here we must import useState
and useEffect
from 'react'
, in order to use them in our function. By setting the state of movies
to an empty array, we have an array to store all of our movies that come in. Our useEffect
function is called only once, and makes a GET
request to our get '/movies'
route. We can then setMovies
to the response we get, which will be the movies from our database.
The handleAddMovie
function will accept a newMovie
argument, which we can set our movies state to all of our movies, plus the newMovie
we pass into this function.
Now we can pass those pieces of state to our MovieList
and NewMovie
components.

In our MovieList
component, we simply iterate over our movies
with the map
method and place our Movie
component inside, where we can pass along attributes of the movie
.

In our Movie.js
file, we use destructuring assignment to define the following variables within our movie.

Then we can display our Movie
in our return statement like so:

Over to our NewMovie
component, where we passed in that handleAddMovie
function as onAddMovie
.

First we create state variables for each of the movie’s attributes that we want to send to our backend, setting their state’s to empty strings. In our return statement, we create a form with an onSubmit
handler, where we pass our (soon to be defined) handleSubmit
function to handle our POST request.

We create inputs for each attribute, and set their values to each piece of state. Then in our onChange
handler, we set their values in state. By setting them to e.target.value
, we’re saying that whatever the client inputs should be define our states. From there we make sure to add a button to click with a type of sumbit
, to ensure our function is called. Finally, onto our fetch request!

Now we define that handleSubmit
function that we passed to our onClick
handler previously. First pass event
and call event.preventDefault()
inside the function. event.preventDefault()
ensures that the page won’t reload upon clicking our Add Movie
button. This is necessary because the default behavior for a button with a submit
type is to refresh the page on submit.
We make the request to our post '/movies
route defined in our backend, sending our title, quote
,and rating
states which are defined when our user inputs values for them. We then call onAddMovie
on the response, adding our new movie to the array holding the rest of our movies. And that’s it! We can now successfully retrieve movies from our database and display them in our React frontend, as well as post new movies to our database, also displaying them to our users.