Search code examples
reactjsreact-hooksuse-effectuse-state

Strange stuff with useState, useEffect and fetch


I'm trying to fetch some data inside useEffect and when the data is received I want to set a certain state with useState. Data correctly returns from the server. However this doesn't work. Here's the code:

const [sharingLink, setSharingLink] = React.useState(null);

React.useEffect(() => {
    client.query({
        query: queryGetReferalData
    }).then(result => {
        console.warn(result); // correct response
        setSharingLink(result.data.referralsystem.shareUrl);
        console.warn(sharingLink); // null
    });
}, []);

Here's the whole component:

import React from 'react';
import styled from 'styled-components';
import { i18n } from 'Helpers';

import { Button } from './Button';
import { ButtonLink } from './ButtonLink';
import { Heading } from './Heading';
import { Input } from './Input';

import Copy from './icons/Copy';
import Facebook from './icons/Facebook';
import Twitter from './icons/Twitter';
import WhatsApp from './icons/WhatsApp';

import client from '@client/apollo';
import queryGetReferalData from './schemas/queryGetReferalData.graphql';

const Root = styled.div`
    padding: 48px;
    padding-top: 32px;

    display: flex;
    align-items: center;
    justify-content: space-between;

    box-shadow: 0px 10px 30px rgba(27, 50, 85, 0.1);
    border-radius: 4px;

    background-color: #FFFFFF;
`;

const Pane = styled.div`

`;

const Row = styled.div`
    display: flex;

    & > * + * {
        margin-left: 10px;
    }
`;

export const Form = () => {
    const [sharingLink, setSharingLink] = React.useState(null);

    const facebookSharingLink =
        sharingLink && `https://www.facebook.com/sharer/sharer.php?${encodeURIComponent(sharingLink)}`;

    const twitterSharingLink = 
        sharingLink && `http://www.twitter.com/share?url=${encodeURIComponent(sharingLink)}`;

    const whatsAppSharingLink = 
        sharingLink && `whatsapp://send?text=${encodeURIComponent(sharingLink)}`;

    React.useEffect(() => {
        client.query({
            query: queryGetReferalData
        }).then(result => {
            console.warn(result);
            setSharingLink(result.data.referralsystem.shareUrl);
            console.warn(sharingLink);
        });
    }, []);

    return (
        <Root>
            <Pane>
                <Heading>
                    { i18n._('Your invitational link') }
                </Heading>
                <Row>
                    <Input disabled={sharingLink === null} value={sharingLink} />
                    <Button icon={<Copy />}>
                        { i18n._('COPY') }
                    </Button>
                </Row>
            </Pane>
            <Pane>
                <Heading>
                    { i18n._('Or share via social') }
                </Heading>
                <Row>
                    <ButtonLink
                        backgroundColor='#5A79B5'
                        icon={<Facebook />}
                        href={facebookSharingLink}
                    >
                        { i18n._('Facebook') }
                    </ButtonLink>
                    <ButtonLink
                        backgroundColor='#52A6DB'
                        icon={<Twitter />}
                        href={twitterSharingLink}
                    >
                        { i18n._('Twitter') }
                    </ButtonLink>
                    <ButtonLink
                        backgroundColor='#0DC455'
                        icon={<WhatsApp />}
                        href={whatsAppSharingLink}
                    >
                        { i18n._('WhatsApp') }
                    </ButtonLink>
                </Row>
            </Pane>
        </Root>
    );
};

The component also renders like sharingLink is null.

  1. Why is this happening?
  2. What do I do to make this work?

Solution

  • I had some code that was adding to the DOM in the parent component. When I remove it, everything works.

    Adding to the DOM in the component, doesn't matter if it's into useEffect or not, somehow messes up hooks even though you add HTML to something completely unrelated to react I guess.

    I had this structure:

    <body>
     <div id="page">
      <div id="root">
       <CustomReactElement />
      </div>
     </div>
    <body>
    

    The code inside CustomReactElement was adding markup to the 'page'. I changed the code from setting an innerHTML to appendChild() and everything worked.