Autosaving with React Hooks
Tags: react, hooks, autosaving, javascript
Published: 2019-12-21 19:12:25

---
title: Autosaving with React Hooks
published: true
description: Autosaving with React hooks is fairly trivial once you understand React's useEffect hook. Autosaving can be accomplished with useEffect and useState.
tags: react, hooks, autosaving
cover_image: https://www.bradcypert.com/wp-content/uploads/2019/12/photo-of-light-bulb-1495580-scaled-e1576955013340.jpg
canonical_url: https://www.bradcypert.com/autosaving-with-react-hooks
---

#### This post is originally from [bradcypert.com](https://www.bradcypert.com/autosaving-with-react-hooks), but has been reformatted for your viewing pleasure on Dev.to!

<!-- wp:paragraph -->
<p>React hooks have really changed the game for me when it comes to building react components. However, I've found that writing autosaving functionality is a little less obvious via hooks. Thankfully, it is still possible (and arguably a lot cleaner) when using hooks.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>We can accomplish autosaving functionality through use of <code>useEffect</code>. You'll also need a way to post the data to your server. In my case, I'm using Apollo's useMutation hook as well. This allows me to post a graphql mutation from a hook-like interface.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>The <code>useEffect</code> hook</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>The <code>useEffect</code> hook effectively replaces <code>componentDidMount</code>, <code>componentWillUpdate</code>, and <code>componentWillUnmount</code>. Here's how I remember the API for <code>useEffect</code>:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>useEffect(() => {
  doWhateverIsHereOnMountandUpdate();

  return () => {
    doWhateverIsHereOnWillUnmount();
  }
}, [skipUntilThisStateOrPropHaschanged])</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>It's worth mentioning that the <code>skipUntilThisStateOrPropHasChanged</code> is optional, and leaving it out will cause it to process the hook on every render.</p>
<!-- /wp:paragraph -->

<!-- wp:heading -->
<h2>Implementing Autosave</h2>
<!-- /wp:heading -->

<!-- wp:paragraph -->
<p>Now that we understand our hook, the autosave functionality becomes fairly trivial. We'll use a couple of state hooks as well to help us manage the text that a user types in as well as the last value we saved (we can skip network requests if they're the same).</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>const [lastText, setLastText] = React.useState('');
const [text, setText] = React.useState('');</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>You'll see how we use <code>lastText</code> in our <code>useEffect</code> hook below, but for now, you just need to know that <code>text</code> represents the state of what the user has typed in. If you'd like more information on how this works, <a href="https://reactjs.org/docs/forms.html#controlled-components">React's documentation for Controlled Components is a great place to start</a>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>Now, we need a function to trigger to persist our data to the server. In my case, I'll use an Apollo mutation since the server API processes graphql.</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>const [updateContent] = useMutation(UPDATE_CHAPTER_CONTENT.MUTATION);</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Finally, we can write our <code>useEffect</code> hook:</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>const AUTOSAVE_INTERVAL = 3000;
React.useEffect(() => {
    const timer = setTimeout(() => {
      if (lastText != text) {
        updateContent({ variables: { content: text, id: chapterId } });
        setLastText(text);
      }
    }, AUTOSAVE_INTERVAL);
    return () => clearTimeout(timer);
  }, [text]);</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>We're doing a couple of neat things here. First, we're setting up our <code>useEffect</code> hook. It creates a timer via <code>setTimeout</code>, and when that hook unmounts, it removes that timer. That's the "meat-and-potatoes" behind it. You'll notice that our setTimeout function checks to see if the text has changed before posting our data, and then sets the last text if it has changed.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>We're also only triggering this <code>useEffect</code> when <code>text</code> has changed (as indicated by <code>[text]</code> as the second parameter. We probably could clean this up a bit by removing the <code>if</code> in the timeout function body, and updating the <code>useEffect</code> dependency array to be <code>[text != lastText]</code>.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>And that should do it! Hopefully, this helps if you're trying to build autosave functionality into React project.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>If you'd like to <a href="https://www.bradcypert.com/tag/react/">learn more about React, you can find my other post on Facebook's awesome framework here.</a></p>
<!-- /wp:paragraph -->