Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite loop / browser tab hang #104

Closed
trbabb opened this issue Sep 6, 2019 · 1 comment
Closed

Infinite loop / browser tab hang #104

trbabb opened this issue Sep 6, 2019 · 1 comment
Labels
duplicate This issue or pull request already exists

Comments

@trbabb
Copy link

trbabb commented Sep 6, 2019

Not sure if this is a recent issue, or perhaps a simple misconfiguration on my end, but either way, I'm pretty stuck— even the simplest react-async example fails. I am using create-react-app with React 16.9.0. Here is a simple App.js which hangs for me:

import React from 'react';
import './App.css';

import {useAsync, IfPending, IfFulfilled, Async} from 'react-async';

function App() {
  const fn = async () => {
    return "foo"
  }
  const state = useAsync({promiseFn:fn})
  return (
    <div className="App">
      <IfPending state={state}>not loaded</IfPending>
      <IfFulfilled state={state}>loaded!</IfFulfilled>
    </div>
  );
}

export default App;

On Chrome this hangs indefinitely for me, and I have to kill the tab using the Chrome task manager (closing the tab doesn't work!). On at least one occasion I've gotten an infinite spew of console errors about a "maximum update depth", but I am unable to repro that consistently. On Firefox, it simply stops responding (including the dev tools) until the tab is closed. The page shows "not loaded" indefinitely and never changes to "loaded!"

I've tried quite a few permutations by following the examples in the docs, and the result is ever the same. What's wrong?

thanks!

@ghengeveld
Copy link
Member

ghengeveld commented Sep 6, 2019

You must either define fn (the promiseFn) outside of App (recommended), or wrap it with useCallback.

const fn = async () => {
  return "foo"
}

function App() {
  const state = useAsync({ promiseFn: fn })
  return (
    <div className="App">
      <IfPending state={state}>not loaded</IfPending>
      <IfFulfilled state={state}>loaded!</IfFulfilled>
    </div>
  );
}

React Async will restart the promiseFn when it changes. Since you're creating the function inside your component body, you're effectively creating a new function every time the component renders. Because it's a new function it will restart the promise, causing state to update, causing a rerender and there you have your infinite loop.

See the notes on promiseFn in the docs (although it's written to apply to the <Async> component, but it applies similarly to useAsync).

There's already an issue that aims to do something about this (i.e. throw an error instead of hanging indefinitely). Therefore I'm closing this.

@ghengeveld ghengeveld added the duplicate This issue or pull request already exists label Sep 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

2 participants