reactive localstorage in react

Reactive LocalStorage in React

Local storage is a simple key-value store that allows web applications to store data in the user's browser. It provides an easy way to persist data across page reloads or sessions. In React, local storage can be used to store data that needs to be shared between components or kept persistent across multiple sessions. However, accessing and manipulating local storage in a reactive way can be tricky. In this article, we will explore how to use local storage in a reactive way in React.

Using React Hooks

One way to use local storage in a reactive way in React is to leverage the power of React Hooks. With the introduction of Hooks in React 16.8, it's now possible to use state and other React features in functional components without having to use class components. The useState hook can be used to create reactive local storage in a functional component.


import React, { useState, useEffect } from 'react';

function App() {
  const [count, setCount] = useState(parseInt(localStorage.getItem('count'), 10) || 0);

  useEffect(() => {
    localStorage.setItem('count', count);
  }, [count]);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <button onClick={() => setCount(count - 1)}>Decrement</button>
    </div>
  );
}

export default App;

In the above code, we are using the useState hook to create a state variable called count. We are initializing the state with the value of localStorage.getItem('count'). If the item doesn't exist in local storage, we are setting the default value to 0. We are then using the useEffect hook to listen to changes in the count state variable. Whenever the count changes, we are updating the local storage with the new value using localStorage.setItem('count', count).

Using Higher-Order Components

Another way to use local storage in a reactive way in React is to use Higher-Order Components (HOCs). HOCs are functions that take a component and return a new component with additional functionality. In this case, we can create an HOC that listens to changes in local storage and passes the updated data to the wrapped component.


import React from 'react';

function withLocalStorage(WrappedComponent, key) {
  return class extends React.Component {
    constructor(props) {
      super(props);

      this.state = {
        data: localStorage.getItem(key),
      };
    }

    componentDidMount() {
      window.addEventListener('storage', this.handleStorageEvent);
    }

    componentWillUnmount() {
      window.removeEventListener('storage', this.handleStorageEvent);
    }

    handleStorageEvent = (event) => {
      if (event.key === key) {
        this.setState({ data: event.newValue });
      }
    };

    render() {
      return <WrappedComponent data={this.state.data} {...this.props} />;
    }
  };
}

export default withLocalStorage;

In the above code, we are creating an HOC called withLocalStorage that takes two arguments - the wrapped component and the key for the local storage item. We are creating a new class that extends React.Component. We are initializing the state with the value of localStorage.getItem(key). We are then using the componentDidMount and componentWillUnmount lifecycle methods to add and remove an event listener on the window object for the 'storage' event. Whenever the 'storage' event is fired and the key matches our local storage key, we are updating the state with the new value using this.setState({ data: event.newValue }). We are then passing the updated data to the wrapped component using <WrappedComponent data={this.state.data} {...this.props} />.

We can then use the HOC with our components like this:


import React from 'react';
import withLocalStorage from './withLocalStorage';

function App(props) {
  const { data } = props;

  return (
    <div>
      <p>Data: {data}</p>
    </div>
  );
}

export default withLocalStorage(App, 'data');

In the above code, we are importing the withLocalStorage HOC and using it with our App component. We are passing the key 'data' to the HOC so that it listens to changes in the 'data' local storage item. We are then using the updated data passed to our component as a prop.

Conclusion

Using local storage in a reactive way in React can be done using Hooks or Higher-Order Components. Both approaches have their pros and cons and can be used depending on the use case. Hooks provide a more concise and modern way of using local storage in functional components, while HOCs provide a more flexible and reusable way of using local storage in class components. Choose the approach that best fits your needs and keep your data reactive!

Subscribe to The Poor Coder | Algorithm Solutions

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
[email protected]
Subscribe