Hi all. i've been trying to set up Growthbook in S...
# sdk-react
b
Hi all. i've been trying to set up Growthbook in Shopify's Hydrogen framework, which is based on Remix. I'm new to React so it is a bit of a learning curve, but I have followed these instructions: https://docs.growthbook.io/lib/react I am getting features through from GB and the tracking callback is being triggered abd I can see the experiment_viewed event in BigQuery. If I set a feature to be always on or off in GB my local site immediately updates. But my 50/50 experiment rule is always coming through as OFF (the first value). I have this:
Copy code
export default function App() {
  ...
      <body>
        <GrowthBookProvider growthbook={gb}>
          <Layout {...data}>
            <Outlet />
          </Layout>
        </GrowthBookProvider>
  ...
}
and then this:
Copy code
export default function Homepage() {
  ...
  const gbFeature = useFeatureIsOn("test-feature");
  console.log(gbFeature)
  ...
}
In another GB implementation it has not been an issue to see different feature values in different browser sessions (incognito windows for example). I am assigning with Google Analytics clientId and I can see this is set (by using the useGrowthBook() method to access GB instance directly), and that it is being set differently in different browser sessions. It is being set via a promise:
Copy code
useEffect(() => {
    // Set user attributes for targeting (from cookie, auth system, etc.)
    gb.setAttributes({
      clientId: getClientId(),
    });
  }, []);
which may mean the value is not available for assigning variation (getClientId awaits a promise). This may or may not be related though. I have got the same underlying approach working in Vue no problem, but may be missing something about React here. Thanks for any advice.
f
It might be a race condition, are you sure that the useFeatureIsOn is happening after the useEffect that sets the attributes?
b
Thanks Graham, the attribute was not being set in time as you say. To make it work I also followed this: https://maxrozen.com/fetching-data-react-with-useeffect and modified App() ended up being as follows. I hope this saves someone some time. This way GB is seemingly ready to go in other components.
Copy code
export default function App() {
  const nonce = useNonce();
  const data = useLoaderData();
  const [gbLoaded, setData] = useState(null);

  useEffect(() => {
    // Load features from the GrowthBook API and initialize the SDK
    const fetchData = async () => {
      await gb.loadFeatures();
      const getClientIdPromise = new Promise((resolve) => {
        ReactGA.gtag('get', 'G-XXX', 'client_id', resolve);
      })
      await getClientIdPromise.then((clientId) => {
        gb.setAttributes({
          clientId,
        });
      })
      setData(gb)
    }
    fetchData().catch(console.error);
  }, []);

  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width,initial-scale=1" />
        <Meta />
        <Links />
      </head>
      <body>
        {gbLoaded &&
          <GrowthBookProvider growthbook={gbLoaded}>
            <Layout {...data}>
            < Outlet />
            </Layout>
          </GrowthBookProvider>
        }
        <ScrollRestoration nonce={nonce} />
        <Scripts nonce={nonce} />
        <LiveReload nonce={nonce} />
      </body>
    </html>
  );
}