React Query: It’s Time to Break up with your "Global State”!

Rate this content
Bookmark

An increasing amount of data in our React applications is coming from remote and asynchronous sources and, even worse, continues to masquerade as "global state". In this talk, you'll get the lowdown on why most of your "global state" isn't really state at all and how React Query can help you fetch, cache and manage your asynchronous data with a fraction of the effort and code that you're used to.

Tanner Linsley
Tanner Linsley
30 min
02 Aug, 2021

Comments

Sign in or register to post your comment.

Video Summary and Transcription

Global state management and the challenges of placing server state in global state are discussed. React Query is introduced as a solution for handling asynchronous server state. The Talk demonstrates the process of extracting logic into custom hooks and fixing issues with state and fetching logic. Optimistic updates with mutation are showcased, along with the benefits of using React Query for data fetching and mutations. The future of global state management is discussed, along with user feedback on React Query. The Talk concludes with an invitation to explore React Query for server state management.

Available in Español

1. Introduction to Global State Management

Short description:

Hi, I'm Tanner Linsley, co-founder and VP of UI and UX at nozzle.io. Today, I want to talk about global state management and the mistake of placing server state in global state. Server state is different from client state in terms of storage, access speed, and ownership. Let's explore why and how we can handle server state more effectively.

Hi everyone. My name is Tanner Linsley, and I'm a co-founder and VP of UI and UX at nozzle.io, where we build SEO rank tracking software for enterprise. I absolutely love React and JavaScript, and I have a bit of an obsession for building open source software as well.

So since learning React, I've been super obsessed with topics like static site generation, data visualization, and animation. But today I'd like to talk to you about what is possibly my favorite one of all, global state management.

Today, a ton of code in our applications is dedicated to consuming and manipulating asynchronous data. Whether that data comes from our users or servers or third party APIs, it's absolutely critical for our apps to provide value to our users. In fact, for a lot of us, our applications are just opinionated user interfaces for consuming and managing this data.

Over the years, I've noticed that patterns around accessing and manipulating our data in our applications have quickly taken up residence with what we all know as global state. Global state is super convenient. It helps us avoid prop drilling, and it lets us access data across our application without copying or duplicating it. And it even helps us communicate between isolated components and hooks that otherwise wouldn't be able to. In the end, it just helps us do more with less code. It's extremely accessible and powerful, so it's only natural that we would want all of our important server side data to be just as accessible as our global state. And with that expectation, it's no surprise that we as React developers have chosen to co-locate our server side data with the rest of our global state.

It's relatively easy to do this by using something like local component state with React context, or even by using any number of libraries from the ever-growing list of global state management tools out there. But in the end, the expectation is usually the same. We expect our global state not only to be able to handle trivial things like menu state, themes, things like toasts and alerts, but we also expect it to be responsible for complex life cycles around fetching and providing our server side and asynchronous data to our users.

So today, I'm here to tell you that despite the fleeting convenience global state gives us when working with server side data, I think we've made a really big mistake by placing it there. We've tricked ourselves and our code into thinking that all state is created equal, when I think our asynchronous data and global state could not be more different, especially when it comes to where they're stored, the speed at which we access them, and how we access and update them, and ultimately who can make changes to them.

To make all this easier to understand, I want to stop using the term global state and instead call these two different types of state client state and server state. Client state is relatively simple and should be familiar to most developers. It's temporary and local, and it's generally not persisted between sessions. It's accessed with synchronous APIs that don't have any latency, and most of it is owned by our client's application instance. So for all those reasons, we can pretty much rely on our client state always being up to date at any given time in our application.

Server state, however, is pretty different. Server state is persisted remotely, so the location source of truth for our server state is potentially unknown, or at least outside of our control. It's asynchronous, so we have to access it with asynchronous APIs, and it also has implied shared ownership, which means that it's not just owned by our client. It can be read and manipulated by both the server and any other potential clients that interact with it. Because of all these things, very few guarantees can actually be made around our server state always being up to date in our apps, and instead we usually end up relying on just snapshots of our async data.

2. Server State and Client State

Short description:

When server state and client state are stored in the same system, tradeoffs are made. Server state has unique challenges that require dedicated tools. React Query is an NPM library that solves asynchronous server state with a small, simple API. To demonstrate its capabilities, I built a blog application with React and Next.js. The app allows viewing, editing, and adding posts. Initially, the app had four main components, each using useEffect and React State for data fetching and loading states. However, I wanted to make the code more portable.

So when we take these two very different types of state, server state and client state, and try and store them in the same system, we'll eventually make tradeoffs that favor one or the other. A good example of this is that server state has its own unique challenges that we never face with client state. For example, a few of these might be things like caching, deduping requests, updating data in the background, dealing with outdated requests, dealing with mutations, pagination and incremental fetching, or even garbage collection, error memory management, and everything else that comes with caching in general. Many global state patterns don't offer solutions for these kinds of challenges, or at the very least attempt to solve them with complicated APIs or overengineered plugin systems, and sometimes even overpowered APIs that are basically foot guns for the average React developer.

Server state and client state clearly both need plenty of love, but they each need it in their own way. And while I think they have a few things in common when it comes to how we access them in our apps, I think it's time for server state and client state to break up. There is way more to server state than just being globally accessible, and I think it deserves new dedicated tools that not only solve these challenges, but automatically handle them in an elegant way. This is exactly why I decided to build React Query. React Query is an NPM library comprised of a couple hooks and utilities that aim to solve asynchronous server state. It's a small API, it's simple, and it's designed to help both novice and advanced React developers be successful while requiring little to zero configuration.

To really know how React Query can drastically transform the way you handle server state, I decided to build a small interactive blog application using React and a little API powered by Next.js. So the purpose of this application is pretty simple. It's to show a list of posts, it lets us look at a detailed view of an individual post, and then it allows us to edit existing posts or add new ones as well. I'm going to navigate through a few stages or commits that I made to this project of how this application's state management evolved in the wild and how, in the end, I finally got to use React Query to save the day.

So first, let's just get familiar with the app. We have a trusty sidebar with a single link into our post page. We have a post page that fetches all of our posts from our API and displays them in a list. We can click on a post and load the detailed view with the full content. We can use the edit form at the bottom to edit the post. And then back on our post list, we can use that same form to add a new post to the list. So to do all of this, our app started out with four main components. An app component, which handles all of our routing and routing state. A post component, which fetches our posts from the API and then displays them with the add new post form underneath them. An individual post component that fetches the full content for a post and renders it and then gives us the edit form at the bottom. And then finally, we have a reusable post form component that just is for editing the post fields. So in each of these post components, right now we're just using a use effect strategy to call an asynchronous function and fetch our data. And then we use React State to keep track of the loading states for those requests. This way, when we mount each of those components, the data gets requested and eventually gets rendered in our UI. And all of this is fine and it works, but I personally don't like having a lot of business logic in my components. So I want to see if we can make this a bit more portable.

QnA

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Everything Beyond State Management in Stores with Pinia
Vue.js London Live 2021Vue.js London Live 2021
34 min
Everything Beyond State Management in Stores with Pinia
Top Content
When we think about Vuex, Pinia, or stores in general we often think about state management and the Flux patterns but not only do stores not always follow the Flux pattern, there is so much more about stores that make them worth using! Plugins, Devtools, server-side rendering, TypeScript integrations... Let's dive into everything beyond state management with Pinia with practical examples about plugins and Devtools to get the most out of your stores.
Using useEffect Effectively
React Advanced Conference 2022React Advanced Conference 2022
30 min
Using useEffect Effectively
Top Content
Can useEffect affect your codebase negatively? From fetching data to fighting with imperative APIs, side effects are one of the biggest sources of frustration in web app development. And let’s be honest, putting everything in useEffect hooks doesn’t help much. In this talk, we'll demystify the useEffect hook and get a better understanding of when (and when not) to use it, as well as discover how declarative effects can make effect management more maintainable in even the most complex React apps.
Jotai Atoms Are Just Functions
React Day Berlin 2022React Day Berlin 2022
22 min
Jotai Atoms Are Just Functions
Top Content
Jotai is a state management library. We have been developing it primarily for React, but it's conceptually not tied to React. It this talk, we will see how Jotai atoms work and learn about the mental model we should have. Atoms are framework-agnostic abstraction to represent states, and they are basically just functions. Understanding the atom abstraction will help designing and implementing states in your applications with Jotai
A Practical Guide for Migrating to Server Components
React Advanced Conference 2023React Advanced Conference 2023
28 min
A Practical Guide for Migrating to Server Components
Server Components are the hot new thing, but so far much of the discourse around them has been abstract. Let's change that. This talk will focus on the practical side of things, providing a roadmap to navigate the migration journey. Starting from an app using the older Next.js pages router and React Query, we’ll break this journey down into a set of actionable, incremental steps, stopping only when we have something shippable that’s clearly superior to what we began with. We’ll also discuss next steps and strategies for gradually embracing more aspects of this transformative paradigm.
Announcing Starbeam: Universal Reactivity
JSNation 2022JSNation 2022
27 min
Announcing Starbeam: Universal Reactivity
Starbeam is a library for building reactive data systems that integrate natively with UI frameworks such as React, Vue, Svelte or Ember. In this talk, Yehuda will announce Starbeam. He will cover the motivation for the library, and then get into the details of how Starbeam reactivity works, and most importantly, how you can use it to build reactive libraries today that will work natively in any UI framework. If you're really adventurous, he will also talk about how you could use Starbeam in an existing app using your framework of choice and talk about the benefits of using Starbeam as the state management system in your application.
React Query and Auth: Who is Responsible for What?
React Advanced Conference 2021React Advanced Conference 2021
19 min
React Query and Auth: Who is Responsible for What?
Top Content
React Query manages server state on the client, and auth manages user sign in/sign up/sign out. Where do these two overlap, and how do you separate concerns? This talk proposes a data flow with custom hooks for both auth and React Query to manage authentication status and user profile updates.

Workshops on related topic

Rethinking Server State with React Query
React Summit 2020React Summit 2020
96 min
Rethinking Server State with React Query
Top Content
Featured Workshop
Tanner Linsley
Tanner Linsley
The distinction between server state and client state in our applications might be a new concept for some, but it is very important to understand when delivering a top-notch user experience. Server state comes with unique problems that often sneak into our applications surprise like:
- Sharing Data across apps- Caching & Persistence- Deduping Requests- Background Updates- Managing “Stale” Data- Pagination & Incremental fetching- Memory & Garbage Collection- Optimistic Updates
Traditional “Global State” managers pretend these challenges don’t exist and this ultimately results in developers building their own on-the-fly attempts to mitigate them.
In this workshop, we will build an application that exposes these issues, allows us to understand them better, and finally turn them from challenges into features using a library designed for managing server-state called React Query.
By the end of the workshop, you will have a better understanding of server state, client state, syncing asynchronous data (mouthful, I know), and React Query.
State Management in React with Context and Hooks
React Summit Remote Edition 2021React Summit Remote Edition 2021
71 min
State Management in React with Context and Hooks
WorkshopFree
Roy Derks
Roy Derks
A lot has changed in the world of state management in React the last few years. Where Redux used to be the main library for this, the introduction of the React Context and Hook APIs has shaken things up. No longer do you need external libraries to handle both component and global state in your applications. In this workshop you'll learn the different approaches to state management in the post-Redux era of React, all based on Hooks! And as a bonus, we'll explore two upcoming state management libraries in the React ecosystem.