Keeping data fresh with componentDidMount

Linked Projects:

Calreact
 
Lesson code - https://github.com/learnetto/calreact/tree/m7-react-router

Thus far, we’ve added React router to our app so that we can navigate to an individual appointment and back to the home page.

But we’ve got a new problem now when we create an appointment.

Let me show you.

Let’s add a new appointment.

And it gets added to the list. 

[screenshot: 0:23]

Now, if I go to view the appointment (it doesn’t matter which one) and then back to the homepage, the new appointment disappears from the list.

[screenshot: 0:30-31]

The reason is that on the homepage we are initially loading the appointments data from the controller, but once React Router takes over, we are just navigating between routes on the client side.

We’re not fetching any new data from the server unless we specifically make a request for it like we do in the Appointment component.

If I refresh the page, the new appointment will reappear because we’re getting the latest appointments data from the controller again.

So we need to add an AJAX call in the Appointments component to fetch the appointments data when we navigate to the home route.

We’ll change the way we get the appointments data into our Appointments component on the homepage.

Let’s go to the Appointments component and add an AJAX call in componentDidMount.

Let’s copy and paste this bit from the Appointment component into Appointments. In it, let’s change the URL to simply appointments and setState appointmentdata

componentDidMount () {
 if(this.props.match) {
  $.ajax({
   type: "GET",
   url: '/appointments',
   dataType: "JSON"
  }).done((data) => {
   this.setState({appointment: data});
  });
 }
}

Now refresh the page and go to an appointment page.

Now let me bring up the Rails console.

Notice that when I click through to the homepage, another get request is made to '/appointments'.

[screenshot: 1:51]

That’s the AJAX call we just added to componentDidMount.

We also need to change our index action in the controller because, in response to our AJAX call, we’re not getting JSON data, we’re just getting HTML.

So we need to add a respond_to block in appointments_controller.rb:

class AppointmentsController < ApplicationController
   def index
   @appointments = Appointment.order('appt_time ASC')
   @appointment = Appointment.new
   respond_to do |format| 
   format.html 
   format.json { render json: @appointments } 
end
 
Now test this change by making a new appointment. Add a title, choose a date and submit the form.

It gets added to the list.

Then go to an individual appointment route. Click back to the homepage.

And the new appointment is still showing in the list.

[screenshot: 2:47]

One other thing we should do is set a default value for the appointments prop in Appointments.jsx. 

export default class Appointments extends React.Component {
    static propTypes = {
   appointments: PropTypes.array.isRequired
    }

    static defaultProps = {
 appointments: []
}

So if it's not passed, we'll set it to an empty array.

Liked this tutorial? Get more like this in your inbox