Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Context API - persist data on page refresh

Let's say we have a context provider set up, along with some initial data property values.

Somewhere along the line, let's say a consumer then modifies those properties.

On page reload, those changes are lost. What is the best way to persist the data so we can retain those data modifications? Any method other than simply local storage?

like image 768
Cog Avatar asked Nov 23 '18 23:11

Cog


People also ask

How do you persist data on refresh React?

To maintain state after a page refresh in React, we can save the state in session storage. const Comp = () => { const [count, setCount] = useState(1); useEffect(() => { setCount(JSON. parse(window. sessionStorage.

Does React context persist data?

Context doesn't persist in the way you want. Here's a sample of what I've done, using stateless functional with React hooks. Understand from the start that this isa workaround, not a permanent solution. Persisting data is the job of a database, not the client.

How do I stop my page from refreshing in React?

Use the preventDefault() method on the event object to prevent a page refresh on form submit in React, e.g. event. preventDefault() . The preventDefault method prevents the browser from issuing the default action which in the case of a form submission is to refresh the page.


2 Answers

Yeah, if you want the data to persist across reloads, your options are going to be storing that info server-side (via an api call) or in browser storage (local storage, session storage, cookies). The option you'll want to use depends on what level of persistence you're looking to achieve. Regardless of storage choice, it would likely look something along the lines of

const MyContext = React.createContext(defaultValue);  class Parent extends React.Component {   setValue = (value) => {         this.setState({ value });   }    state = {     setValue: this.setValue,     value: localStorage.getItem("parentValueKey")   }    componentDidUpdate(prevProps, prevState) {     if (this.state.value !== prevState.value) {       // Whatever storage mechanism you end up deciding to use.       localStorage.setItem("parentValueKey", this.state.value)     }   }    render() {     return (       <MyContext.Provider value={this.state}>         {this.props.children}       </MyContext.Provider>     )   } } 
like image 174
TLadd Avatar answered Sep 18 '22 23:09

TLadd


Context doesn't persist in the way you want. Here's a sample of what I've done, using stateless functional with React hooks.

import React,  {useState, useEffect} from 'react'  export function sample(){   // useState React hook   const [data, setData] = useState({})   const [moreData, setMoreData] = useState([])    // useState React hook   useEffect(() => {      setData({test: "sample", user: "some person"})     setMoreData(["test", "string"])   }, [])    return data, moreData }  export const AppContext = React.createContext()  export const AppProvider = props => (   <AppContext.Provider value={{ ...sample() }}>     {props.children}   </AppContext.Provider> )  

Understand from the start that this isa workaround, not a permanent solution. Persisting data is the job of a database, not the client. However, if you need persisted data for development, this is one way. Notice first that I'm using React hooks. This is a fully supported feature as of 16.8. The useEffect() replaces the lifecycle methods found in class declarations like that of TLadd above. He's using componentDidUpdate to persist. The most up-to-date way of doing this is useEffect. When the app is refreshed this method will be called and set some hard-coded data in context.

To use the provider:

import React from 'react' import Component from './path/to/component' import { AppProvider } from './path/to/context'  const App = () => {   return (     <AppProvider>       <Component />     </AppProvider>   ) } 

When you refresh, data and moreData will still have whatever default values you assign to them.

like image 43
Jonathan Whittle Avatar answered Sep 20 '22 23:09

Jonathan Whittle