launchdarkly / react-client-sdk

LaunchDarkly Client-side SDK for React.js
Other
86 stars 70 forks source link

allow ldClient to be initialized manually #39

Closed bezreyhan closed 4 years ago

bezreyhan commented 4 years ago

Related issues

There are a couple of open issues that relate to this PR. The main issue I am addressing is the fact that the LD React SDK will initialize the ldClient on componentDidMount. The problem we are facing is that our user object is fetched asynchronously, so SDK always assumes that our user is anonymous and fetches flags for an anonymous user. This can cause a flash since the flags fetched for the anonymous user can be different from the authenticated user. Additionally, we incur an extra MAU for the anonymous user. I believe this is also affecting our partial rollouts since the number of users is not accurate. This has prevented us from using the insights feature.

Describe the solution you've provided My solution was to create a function called initLDClient that gets passed through context. This will allow the user to manually call initLDClient once the user object has been fetched. I also added reactOptions.manualyInitializeLDClient which will prevent the SDK from automatically initializing.

Provide a clear and concise description of what you expect to happen.

Describe alternatives you've considered Another approach will be to export LDProvider as a standalone component and make the initialization of ldClient be reactive to the existence of a user object. In other words, the ldClient will only initialize once a user object has been provided.

Since we are using Next.js we were not able to use withLDProvider to wrap our app. We had to use a workaround where the LDProvider only wraps a subset of our app. our solution looks something like this:

export const withLDProvider = withLDProviderOriginal({
  clientSideID: getConfig('launchDarkly.clientSideId'),
});
const LDProviderInner = ({ children }: { children: any }) => {
  return children;
};
export const LDProvider = withLDProvider(LDProviderInner);

https://github.com/launchdarkly/react-client-sdk/pull/28 looks like it creates a standalone LDProvider, but it still initializes the ldClient on componentDidMount. If it's preferred, I may be able to fork that PR and that that functionality.

I have not written any tests for this PR. I am happy to do so if LD is happy with this implementation.

This is an important problem for us to fix so we are happy to help to get this over the finish line. Thanks!

bwoskow-ld commented 4 years ago

Hi @bezreyhan ,

I merged #31 just now. I'm going to close this PR in favor of #31 / #40.