Hey everyone! I'm trying to get gb setup in my re...
# ask-questions
f
Hey everyone! I'm trying to get gb setup in my react app for the first time and I'm struggling to get the chrome extension working. Getting this error message in the console : "Could not establish connection. Receiving end does not exist." Also, when I look at the window._growthhook object, debug is set to false even though I initialize with enableDevMode as true.
f
Hi James
can you share the code you’re using?
f
Copy code
const growthbook = new GrowthBook({
    apiHost: "<https://cdn.growthbook.io>",
    clientKey: "REDACTED",
    enableDevMode: true,
    trackingCallback: (experiment, result) => {
        // TODO: Use your real analytics tracking system
        console.log("Viewed Experiment", {
            experimentId: experiment.key,
            variationId: result.key
        });
    }
});

useEffect(()=>{
    growthbook.loadFeatures({autoRefresh: true});
},[])
I got the Chrome Extension to work...but I'm still not able to get growthbook to load in a "ready" state.
Then, in my component I'm doing this :
Copy code
const useEasy = useFeatureIsOn('easylocation');
if I do
Copy code
const f = useFeature("easylocation");
Then i get this :
If I use the chrome extension to override then I can get it to flip and source changes to "override"
image.png
and the gb object is never going to ready : true
f
Sounds like it’s not downloading the features
Do you see the network request for the feature payload?
f
yes...I do...the failure mode seems very odd - because I can toggle it between working and not working simply by having my app start up with a different default route. When it's not working - it appears to be functioning as expected but then it breaks. In other words, if I console.log the status of the feature - it logs once in a good state (and I can actually see the state flash correctly in the UX for a fraction of a second) and then it logs in the broken state. There is no difference in the way the growthbook code is loaded in either method.
good state : window._growthbrook.ready = true, source = "defaultValue" on my feature. bad state = window._growthbrook.ready = true, source = "unknownFeature"
f
huh
maybe debug the useEffect to make sure its firing correctly?
you can also book some time with us next week for some help debugging
f
Copy code
import {useEffect, useRef, useState} from "react";

const useGb = (props = {}) => {

    const {feature, fallbackValue, fallbackTimer = 200} = props;

    const [ready,setReady] = useState(false);
    const [featureDetail, setFeatureDetail] = useState(undefined);

    const gbRef = useRef();
    const timerRef = useRef();
    const fallbackRef = useRef();

    useEffect(()=>{
        if(timerRef.current) {return}
        timerRef.current = setInterval(()=>{
            if(window._growthbook && window._growthbook?.ready) {
                gbRef.current = window._growthbook;
                setReady(true);
                setFeatureDetail(gbRef.current.feature(feature));
                clearInterval(timerRef.current)
            }
        },1000)

        if(!!feature && !!fallbackValue) {
            fallbackRef.current = setTimeout(() => {
                var cur = undefined;
                setFeatureDetail(val => {
                    if (!!val) {
                        return val;
                    } else {
                        return {value: fallbackValue, isFallback: true}
                    }
                })
            }, [fallbackTimer])
        }

        return () => {
            if(timerRef.current) {
                clearInterval(timerRef.current)
            }
            if(fallbackRef) {
                clearTimeout(fallbackRef);
            }
        }

    },[])

    return {
        growthbook: gbRef.current,
        ready: ready,
        value: featureDetail?.value,
        detail: featureDetail
    }

}

export default useGb;
I ended up writing my own useGb hook that seems to be working. I'm directly accessing the window._growthbook object and taking care not to stomp on it.
(I also stuck the feature access stuff in this hook because it covered my use case...)