Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save bvaughn/982ab689a41097237f6e9860db7ca8d6 to your computer and use it in GitHub Desktop.

Select an option

Save bvaughn/982ab689a41097237f6e9860db7ca8d6 to your computer and use it in GitHub Desktop.

Revisions

  1. bvaughn revised this gist Aug 9, 2019. 1 changed file with 1 addition and 1 deletion.
    Original file line number Diff line number Diff line change
    @@ -27,7 +27,7 @@ class ExampleComponent extends React.Component {
    }

    componentDidUpdate(prevProps, prevState) {
    if (prevState.externalData === null) {
    if (this.state.externalData === null) {
    this._loadAsyncData(this.props.id);
    }
    }
  2. bvaughn revised this gist Mar 28, 2018. 1 changed file with 19 additions and 9 deletions.
    28 changes: 19 additions & 9 deletions updating-external-data-when-props-changes-using-promises.js
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@
    // If you are using an async mechanism that does not support cancellation (e.g. a Promise).

    class ExampleComponent extends React.Component {
    _hasUnmounted = false;
    _currentId = null;

    state = {
    externalData: null
    @@ -23,17 +23,19 @@ class ExampleComponent extends React.Component {
    }

    componentDidMount() {
    this._loadAsyncData();
    this._loadAsyncData(this.props.id);
    }

    componentDidUpdate(prevProps, prevState) {
    if (prevState.externalData === null) {
    this._loadAsyncData();
    this._loadAsyncData(this.props.id);
    }
    }

    componentWillUnmount() {
    this._hasUnmounted = true;
    // Prevent potential setState calls after unmount,
    // (Since these trigger DEV warnigs)
    _currentId = null;
    }

    render() {
    @@ -44,11 +46,19 @@ class ExampleComponent extends React.Component {
    }
    }

    _loadAsyncData() {
    asyncLoadData(this.props.id).then(externalData => {
    if (!this._hasUnmounted) {
    _loadAsyncData(id) {
    if (id === this._currentId) {
    // Data for this id is already loading
    }

    this._currentId = id;

    asyncLoadData(id).then(externalData => {
    // Only update state if the Promise that has just resolved,
    // Reflects the most recently requested external data.
    if (id === this._currentId) {
    this.setState({ externalData });
    }
    );
    });
    }
    }
    }
  3. bvaughn revised this gist Feb 14, 2018. 1 changed file with 8 additions and 4 deletions.
    12 changes: 8 additions & 4 deletions updating-external-data-when-props-changes-using-promises.js
    Original file line number Diff line number Diff line change
    @@ -2,6 +2,8 @@
    // If you are using an async mechanism that does not support cancellation (e.g. a Promise).

    class ExampleComponent extends React.Component {
    _hasUnmounted = false;

    state = {
    externalData: null
    };
    @@ -21,12 +23,12 @@ class ExampleComponent extends React.Component {
    }

    componentDidMount() {
    _loadAsyncData();
    this._loadAsyncData();
    }

    componentDidUpdate(prevProps, prevState) {
    if (prevState.externalData === null) {
    this._loadUserData();
    this._loadAsyncData();
    }
    }

    @@ -43,8 +45,10 @@ class ExampleComponent extends React.Component {
    }

    _loadAsyncData() {
    asyncLoadData(this.props.id).then(externalData =>
    this.setState({ externalData })
    asyncLoadData(this.props.id).then(externalData => {
    if (!this._hasUnmounted) {
    this.setState({ externalData });
    }
    );
    }
    }
  4. bvaughn created this gist Feb 14, 2018.
    50 changes: 50 additions & 0 deletions updating-external-data-when-props-changes-using-promises.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,50 @@
    // This is an example of how to fetch external data in response to updated props,
    // If you are using an async mechanism that does not support cancellation (e.g. a Promise).

    class ExampleComponent extends React.Component {
    state = {
    externalData: null
    };

    static getDerivedStateFromProps(nextProps, prevState) {
    // Store prevId in state so we can compare when props change.
    // Clear out previously-loaded data (so we don't render stale stuff).
    if (nextProps.id !== prevState.prevId) {
    return {
    externalData: null,
    prevId: nextProps.id
    };
    }

    // No state update necessary
    return null;
    }

    componentDidMount() {
    _loadAsyncData();
    }

    componentDidUpdate(prevProps, prevState) {
    if (prevState.externalData === null) {
    this._loadUserData();
    }
    }

    componentWillUnmount() {
    this._hasUnmounted = true;
    }

    render() {
    if (this.state.externalData === null) {
    // Render loading state ...
    } else {
    // Render real UI ...
    }
    }

    _loadAsyncData() {
    asyncLoadData(this.props.id).then(externalData =>
    this.setState({ externalData })
    );
    }
    }