How to update React state on nested objects that are serialized in Rails
Tags: rails, react, ruby, javascript
Published: 2023-01-12 16:44:35

**Introduction**

While working on my phase-4 project at Flatiron School I was confronted with the task of repeatedly having to update nested state. This was due to the fact that I was accessing data in different models through the use of serializers in Rails, as opposed to making get requests for each model. While this is beneficial in terms of how fast the website is, this created the obstacle of figuring out how to update nested state. As this is something I struggled with for a while and it took a while for this concept to click in my head, I thought I would share what I learned, in case someone else out there is struggling as well.

**Project Concept**

Big Apple Runners is an application built for runners to find routes in NYC and write reviews on them to share with each other. It is a single page full-stack CRUD application with a Ruby / Ruby on Rails backend and a React / Javascript frontend.

**Big Apple Runners Models**

User
- Has many reviews
- Has many routes through reviews

Route
- Has many reviews
- Has many users through reviews

Review
- Belongs to route
- Belongs to user

**What is state?**

State is a built-in React object that is used to contain data or information about the component. A component’s state can change over time. Whenever its state changes the component re-renders. This change in state can happen as a response to a user action or event, and these changes determine the behavior of the component and how it will render.

**What are serializers?**

ActiveModel::Serializer provides a simplified way to customize how the JSON rendered by our controllers is structured. Active Model Serializer provides a convention-based approach to serializing our resources. Meaning that if we have a "Route" model, we can also have a "RouteSerializer" serializer and Rails will default to use our serializer if we simply call "render json: route" in our controller.

Within the serializer we can use the built in Active Record macros "has_many" and "belongs_to" to tell Rails which model data we want to gain access to through the serializer. All we have to do is use the same macros in the serializers that we used to set up associations in our model files. Rails then automatically uses the appropriate serializer, based on naming conventions, to display the associated data for each of our models.

From a front end perspective this is great because you don't have to make as many fetch requests, but the data you now have access to are nested objects in the data you are fetching from. This means you have to update the state of nested objects which takes a bit more work on your end.

**How to:**

In the app component I made a GET request to "/routes":  

![Fetch Routes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ek9cfjhw6a8vk7ybwtc.png)

Instead of making a separate fetch request to "/reviews" to access the reviews data, I created a "RouteSerializer" that I told to access the "reviews" model

![Route Serializer](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8gq68bmedvevm92yrs7t.png)

Next I updated nested state to have access to the object. It is important to note that because review data is accessed through "/routes" the state that needs to be updated is the route state. But in order to access reviews, which is nested we need to iterate twice, first through routes to get to reviews and then through reviews in order to access whatever is it is we are trying to change in reviews.  

![Delete Review](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rzzwsvp74yz37rtirdll.png)

![Add Review](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4398cch6cqcf5it51ofc.png)

![Update Review](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rjxysc2tmoaca44cvmfd.png)

**Conclusion**

I hope this was helpful if you are feeling stuck on how to update nested state. I'm sure there are other ways you can do so, but this was the way that worked and made more sense to me.