1
\$\begingroup\$

I'm starting using hooks, and I have a specific scenario that I'm thinking useEffectis appropriate for.

Essentially what I'm doing is:

  • I have some ssiData in the redux store.
  • If that data has an invite code, and the invite isn't already accepted, then I want to display a QR code
  • If the invite is accepted, then this component will not be displayed.
  • If I am displaying the QR code, then I want to dispatch an action that is going to poll for updates to the ssiData
  • But if the user navigates away - I want to cancel the polling.
  • If the connection is accepted while the QR is displayed, I want to stop polling, and the QR to disappear.

The idea is - the QR is displayed to the user, they use their phone to scan it to accept the invite.

So the way I've done this is:

function SsiQrCodeRender({ ssiData, pollForChanges, cancelPolling }) {
    const classes = useStyles();
    const image = "data:image/png;base64," + qrImage.imageSync(JSON.stringify(ssiData.invite)).toString('base64');
    useEffect(() => {
        pollForChanges(ssiData.ssiId)
        return () => {
            cancelPolling();
        }
    })
    return <Card
        component="section"
    >
        <img src={image} className={classes.root} />

    </Card>;
}


const mapStateToProps = (
    state,
    ownProps
) => {
    return {
        ssiData: ssiInitConnectionRedux.dataSelector(state)
    };
};

const mapDispatchToProps = dispatch => {
    return {
        pollForChanges: (ssiId) => dispatch(ssiPollForConnectionChangeRedux.actionFn(ssiId)),
        cancelPolling: () => dispatch(ssiCancelPolling.actionFn()),
    };
};
export const SsiQrCode = connect(
    mapStateToProps,
    mapDispatchToProps
)(SsiQrCodeRender);

And the parent component (simplified):

function SsiStudentLinkPanelRender({ ssiData, doDisplayQr }) {
    const classes = useStyles();
    return <Card 
        component = "section" 
        className={classes.root}>

        {doDisplayQr && <SsiQrCode />}

    </Card>;
}

const doDisplayQrSelector = (ssiData) => {
    return  ssiData.invite && ssiData.connectionState !==4 ; 
}

const mapStateToProps = (
    state,
    ownProps
) => {

    const ssiData = ssiInitConnectionRedux.dataSelector(state); 

    return {
        ssiData, 
        doDisplayQr: doDisplayQrSelector(ssiData), 
    };
};

const mapDispatchToProps = dispatch => {
    return {

};
export const SsiStudentLinkPanel =  connect(
    mapStateToProps,
    mapDispatchToProps
)(SsiStudentLinkPanelRender);

Am I going about this the right way? What I've got so far seems to work ok (although I haven't actually implemented the start polling/stop polling actions).

There's something that seems a bit complicated and flakey with this.

Is this code written such that it will necessarily have a one to one mapping of 'start polling' to 'stop polling' actions?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.