Search code examples
react-nativeasynchronoussetstate

use setState as asynchronous function to save data


I'm trying to update a state in my react native component and i need to save this state to storage. As setState is asyncronous i tried to pass a callback to setState like this :

 setData(
        {
          ...data,
          visible: true,
          color: Theme.COLORS.SUCCESS,
          message: 'Vous êtes connecter avec succès.',
          loading: false,
          person: response,
          token: response.data.token,
          refreshToken: response.data.refreshToken,
        },
        () => {
          console.log(token);
        },
      );

I got this warning : state updates from the usestate() and usereducer() hooks don't support the second callback argument..

How can i use the setState as a synchronous function ? and if it's not possible what's the alternative ?


Solution

  • You can't. But whenever you update the component's state, the component is going to be [eventually] re-rendered.

    If your goal is to persist component state to storage, you could go with something like this:

    class SomeComp extends React.Component {
      componentDidMount() {
        this.setState(localstorage.getItem('somekey'))
      }
    
      componentDidUpdate(_prevProps, _prevState, _snapshot) {
        localstorage.setItem('somekey', JSON.stringify(this.state))
      }
    }
    

    If personally use this hook for this same purpose:

    import ls from 'local-storage'
    import { useState } from 'react'
    
    // useState, but value is retrieved from local storage first time,
    // and stored in local storage when updated
    const useLSBackedState = (defaultValue, localStorageKey) => {
      const lsValue = ls.get(localStorageKey)
      const [value, doSetValue] = useState(
        lsValue === undefined ? defaultValue : lsValue
      )
    
      const setValue = value => {
        if (typeof value === 'function') {
          doSetValue(v => {
            const newValue = value(v)
            ls.set(localStorageKey, newValue)
            return newValue
          })
        } else {
          doSetValue(value)
          ls.set(localStorageKey, value)
        }
      }
    
      return [value, setValue]
    }
    
    // SomeComponent.js
    const SomeComponent = _props => {
      const [sidebarOpen, setSidebarOpen] = useLSBackedState(false, 'sidebarOpen')
      // ...
    }