Skip to content

Conversation

@spiceboi
Copy link

@spiceboi spiceboi commented Mar 5, 2019

  • Enables useContext API by exporting non-destructured React Context.
  • Non-destructive API change.
  • Verified working with given example.

Can't wait to get this released!

import React, { useContext } from 'react';
import { LDReactContext } from 'ldclient-react';

export default function Home() {
  const { flags } = useContext(LDReactContext)
  return (
    <Root>
      <Heading>Welcome to ldclient-react Example App</Heading>
      <div>
        To run this example:
        <ul>
          <ListItem>
            In app.js, set clientSideID to your own Client-side ID. You can find this in your ld portal under Account
            settings / Projects.
          </ListItem>
          <ListItem>
            Create a flag called dev-test-flag in your project. Make sure you make it available for the client side js
            sdk.
          </ListItem>
          <ListItem>Turn the flag on and off to see this app respond without a browser refresh.</ListItem>
        </ul>
      </div>
      <FlagDisplay>{flags.devTestFlag ? <FlagOn>Flag on</FlagOn> : <span>Flag off</span>}</FlagDisplay>
    </Root>
  );
}

@yusinto
Copy link
Contributor

yusinto commented Mar 8, 2019

Hi there @spiceboi thank you for submitting this pr. We are excited to see the community is as excited as us about using hooks and the react sdk. We are planning to fully support hooks with the react sdk and while your implementation works, there is already work in progress for this. There is no exact eta at this time, but it is already in progress and will be available soon. We are excited to see what the community builds with hooks and the react sdk.

@spiceboi spiceboi closed this Mar 11, 2019
@spiceboi spiceboi deleted the enhancement/143-export-react-context branch March 11, 2019 15:10
eli-darkly added a commit that referenced this pull request Mar 12, 2019
don't send extra feature events when getting flags from Electron main client
@edvinerikson
Copy link
Contributor

If anyone is interested.. this is what I use in React. The datalayer thing may perhaps not be needed in usual cases..

<LaunchDarkly user={...} sdkKey="..."><App /></LaunchDarkly>

// App.js
const [enabled, track] = useFlag('my-feature', false);
import React, {
  useState,
  useEffect,
  createContext,
  useRef,
  useContext,
  useMemo
} from "react";
import { initialize } from "ldclient-js";

const LaunchDarklyContext = createContext(null);
const UserContext = createContext(null);

export function LaunchDarkly({ children, user, sdkKey }) {
  const client = useRef(null);

  // create client with initial user. Sdkkey cannot change overtiem with this impl.
  if (client.current == null) {
    client.current = initialize(sdkKey, user, {
      sendEventsOnlyForVariation: true,
      evaluationReasons: true
    });
  }

  useEffect(() => {
    client.current.identify(user);
  }, [user]);

  return (
    <UserContext.Provider value={user}>
      <LaunchDarklyContext.Provider value={client}>
        {children}
      </LaunchDarklyContext.Provider>
    </UserContext.Provider>
  );
}

export function useFlag(flagName, defaultValue) {
  const user = useContext(UserContext);
  const client = useContext(LaunchDarklyContext);
  const [flagDetails, setFlagDetails] = useState(() =>
    client.current.variationDetail(flagName, defaultValue)
  );

  function internalTrack(extraDataToSend) {
    console.log("Track this");
    if (flagDetails) {
      global.dataLayer.push({
        event: "launchdarkly_feature_impression",
        launchDarklyUser: JSON.stringify(user),
        launchDarklyDetails: JSON.stringify(flagDetails)
      });
    }
  }

  const trackRef = useRef(internalTrack);

  useEffect(() => {
    trackRef.current = internalTrack;
  });

  useEffect(() => {
    const details = client.current.variationDetail(flagName, defaultValue);
    setFlagDetails(details);
  }, [flagName, defaultValue]);

  useEffect(() => {
    let shouldUpdate = true;
    function update() {
      if (shouldUpdate) {
        const details = client.current.variationDetail(flagName, defaultValue);
        setFlagDetails(details);
      }
    }
    client.current.on(`change:${flagName}`, update);
    return () => {
      shouldUpdate = false;
      client.current.off(`change:${flagName}`, update);
    };
  }, [flagName, defaultValue]);

  const trackFn = useMemo(() => data => trackRef.current(data), []);
  console.log(flagDetails);
  return [flagDetails.value, trackFn];
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants