Skip to content

Instantly share code, notes, and snippets.

@bvaughn
Last active November 30, 2022 21:16
Show Gist options
  • Star 67 You must be signed in to star a gist
  • Fork 11 You must be signed in to fork a gist
  • Save bvaughn/89700e525ff423a75ffb63b1b1e30a8f to your computer and use it in GitHub Desktop.
Save bvaughn/89700e525ff423a75ffb63b1b1e30a8f to your computer and use it in GitHub Desktop.
Advanced example for eagerly prefetching async data in a React component.
// This is an advanced example! It is not intended for use in application code.
// Libraries like Relay may make use of this technique to save some time on low-end mobile devices.
// Most components should just initiate async requests in componentDidMount.
class ExampleComponent extends React.Component {
_hasUnmounted = false;
state = {
externalData: null,
};
constructor(props) {
super(props);
// Prime an external cache as early as possible.
// Async requests are unlikely to complete before render anyway,
// So we aren't missing out by not providing a callback here.
asyncLoadData(this.props.someId);
}
componentDidMount() {
// Now that this component has mounted,
// Wait for earlier pre-fetch to complete and update its state.
// (This assumes some kind of external cache to avoid duplicate requests.)
asyncLoadData(this.props.someId).then(externalData => {
if (!this._hasUnmounted) {
this.setState({ externalData });
}
});
}
componentWillUnmount() {
this._hasUnmounted = true;
}
render() {
if (this.state.externalData === null) {
// Render loading state ...
} else {
// Render real UI ...
}
}
}
@petetnt
Copy link

petetnt commented Mar 27, 2018

@mqklin
Copy link

mqklin commented Mar 30, 2018

So constructor is being called before componentDidMount ?

@aryzle
Copy link

aryzle commented Mar 30, 2018

@mqklin yes

@kvedantmahajan
Copy link

kvedantmahajan commented Nov 28, 2018

To avoid caching, what if we did @bvaughn

constructor(props) {
    super(props);
    this.myPromise = asyncLoadData(this.props.someId);
  }
componentDidMount() {
    this.myPromise.then(externalData => {
      if (!this._hasUnmounted) {
        this.setState({ externalData });
      }
    });
  }

@dangeezz
Copy link

@kushalmahajan I think that should avoid caching since you have a pending Promise to be fulfilled with your data;

@VahidBo
Copy link

VahidBo commented Oct 2, 2019

Whay if we do like this???

  constructor(props) {
    super(props);
    asyncLoadData(this.props.someId).then(externalData => {
      if (!this._hasUnmounted) {
        this.setState({ externalData });
      }
    });
  }

@imoppa
Copy link

imoppa commented Jan 17, 2020

Why context is not available in the constructor level? I think it makes sense to have this.context available in the constructor level.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment