DEV Community

Cover image for Make your state safe
Marat Latypov
Marat Latypov

Posted on

Make your state safe

Imagine you have a simple component Post which just renders a post page.

export const Post = (): JSX.Element => {
  const [value, setValue] = useState<string>()
  const url = 'http://somewhere.com/something'

  useEffect(() => {
    axios.get(url).then<string>((response) => {
      setValue(response.data)
    })
  }, [])

  return <div>{value}</div>
}

Enter fullscreen mode Exit fullscreen mode

Just for simplicity purpose let's output just a single string.

And now a question: What will be if we go to another page (or Post component will be unmounted in some other way) before the data load finish?

In this case we will get this warning in the console:

Image description

Nothing is broken. The app still works. App users may not even notice any problems except for the red warning in the console.

You can leave it as is, but you should know that each such event causes a memory leak. At some point, it could become a problem.

The easiest solution is to use the useSafeState hook from the ahooks package. Just replace your useState with useSafeState, and everything will work out of the box.

const [value, setValue] = useSafeState<string>();
Enter fullscreen mode Exit fullscreen mode

I highly recommend to check the source code of useSafeState and research how it works. The code is not too large, so it's not a big deal.

By the way useSafeState under the hood uses highly usefull useUnmountedRef hook, which checks if component is unmounted.

However, that is a topic for another story :)

Top comments (2)

Collapse
 
brense profile image
Rense Bakker

Hmm I'm not sure about this... It seems nice at first but people will use this hook to obscure the fact that they're forgetting to cleanup their side effects... I would not recommend people use this... If it's really a problem and its not fixable by doing correct side effect cleanup, you can implement your own isMounted check pretty easily... Putting that check in a blackbox obscures what is really going on in the side effect. The naming of the hook further encourages people to think that this is a safe way to fix this error, which it isn't... If it had a more verbose name like: useStateOnlyWhenMounted, it would be more clear what is going on.

Collapse
 
altesack profile image
Marat Latypov

In my opinion, moving code parts to reusable functions is a good practice. It helps and doesn't obscure.

But yes, the naming is not the best. It's up to the 'ahooks' developers.

And I agree, may not be a great idea to install additional package just for one tiny hook, which can be easily written from scratch