0.0.3 • Published 3 years ago

react-async-state v0.0.3

Weekly downloads
96
License
ISC
Repository
-
Last release
3 years ago

React Async State

React higher order componet that helps you to work with async data

build status npm version npm downloads

npm install --save --save-exact react-async-state

Motivation

How many times did you struggle with this error?

> Uncaught Error: Invariant Violation: replaceState(...): Can only update a mounted or mounting component.

Yes React.createClass allowed you to check this.isMounted() but new fancy es6 classes dropped this functionality and it's become an antipattern.

So everything you can do is to use (or make your own) cancelable promises or implement your own isMounted functionality.

But hey!

You got flux/redux/anyux tools that will control your async data flow and everything you need is to subscribe and unsubscribe to it's stores.

So why you need this tool ?

In most cases you don't.

Still why ?

Let's assume you got simplest component - FacebookLoginButton and everything you want it to do is to pass to it's parent accessToken if user will click on it and go through authorization steps. And the most important is that this component can be mounted and unmounted at any time. And you really really really don't want to create store for it.

Easy peasy:

export default class FacebookLoginButton extends Component {
    componentDidMount() {
        loadFB().then(FB => {
            this.setState({FB});
        });
    }

    render() {
        return (
            <button onClick={() => this.state.FB.login()}>
                Sign in with Facebook
            </button>
        );
    }
}
Does it look wrong?
  • First - you should disable click when FB is undefined.
  • Second - cancel the promise.
export default class FacebookLoginButton extends Component {
    componentDidMount() {
        loadFB().then(FB => {
            if (!this._cancelPromise) {
                this.setState({FB});
            }
        });
    }

    componentWillUnmount() {
        this._cancelPromise = true;
    }

    render() {
        return (
            <button
                disabled={!this.state.FB}
                onClick={() => this.state.FB.login()}>
                Sign in with Facebook
            </button>
        );
    }
}
Done what next?

You will need to implement GoogleLoginButton, TwitterLoginButton, AnyOtherSocialLoginButton.

Use react-async-state !
import {
    AsyncState
} from 'react-async-state';

const decorator = AsyncState(() => loadFB().then(FB => ({FB})));

class FacebookLoginButton extends Component {
     render() {
        return (
            <button
                disabled={!this.props.FB}
                onClick={() => this.props.FB.login()}>
                Sign in with Facebook
            </button>
        );
    }
}

export default decorator(FacebookLoginButton);
Or if you like es7 syntax
import {
    AsyncState
} from 'react-async-state';

@AsyncState(async () => ({
    FB: await loadFB()
}))
export default class FacebookLoginButton extends Component {
    render() {
        return (
            <button
                disabled={!this.props.FB}
                onClick={() => this.props.FB.login()}>
                Sign in with Facebook
            </button>
        );
    }
}

Examples

License

MIT

0.4.0

3 years ago

0.3.0

3 years ago

0.2.4

3 years ago

0.2.3

3 years ago

0.2.1

3 years ago

0.2.0

3 years ago

0.1.0

3 years ago

0.0.9

3 years ago

0.0.8

3 years ago

0.0.7

8 years ago

0.0.6

8 years ago

0.0.5

8 years ago

0.0.4

8 years ago

0.0.3

3 years ago

0.0.2

3 years ago

0.0.1

3 years ago