This message was deleted.
# ask-questions
w
This message was deleted.
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"
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...)
138 Views