Skip to content

Users are getting null is not an object (evaluating 'n.state.client.lastUpdate') #198

@neriyarden

Description

@neriyarden

Hey,
I don't know if this is a widespread issue or just an issue on my end.
I'm seeing a big amount of errors in Sentry of this issue:

TypeError
_this.update(@splitsoftware+splitio-react@1.12.0_react@18.3.1/node_modules/@splitsoftware/splitio-react/es/SplitClient)
Unhandled: null is not an object (evaluating 'n.state.client.lastUpdate')

After searching the web and finding nothing about this issue, I dove into the code and found where I think the error occurs:

  // Attach listeners for SDK events, to update state if client status change.
  // The listeners take into account the value of `updateOnSdk***` props.
  subscribeToEvents(client: SplitIO.IBrowserClient | null) {
    if (client) {
      const statusOnEffect = getStatus(client);
      const status = this.state;

      if (this.props.updateOnSdkReady) {
        if (!statusOnEffect.isReady) client.once(client.Event.SDK_READY, this.update);
        else if (!status.isReady) this.update();
      }
      if (this.props.updateOnSdkReadyFromCache) {
        if (!statusOnEffect.isReadyFromCache) client.once(client.Event.SDK_READY_FROM_CACHE, this.update);
        else if (!status.isReadyFromCache) this.update();
      }
      if (this.props.updateOnSdkTimedout) {
        if (!statusOnEffect.hasTimedout) client.once(client.Event.SDK_READY_TIMED_OUT, this.update);
        else if (!status.hasTimedout) this.update();
      }
      if (this.props.updateOnSdkUpdate) client.on(client.Event.SDK_UPDATE, this.update);
    }
  }

This is my setup of the SplitClient:

import { useEffect, useState } from "react";
import {
  SplitClient,
  SplitFactoryProvider,
} from "@splitsoftware/splitio-react";

import { analytics } from "@flare/analytics";

const DUMMY_SPLIT_KEY = "anonymous";

export const SplitProvider = ({ children }: { children: React.ReactNode }) => {
  const [anonymousId, setAnonymousId] = useState<string | null | undefined>();

  useEffect(() => {
    async function getAnonymousId() {
      const aId = await analytics.getAnonymousId();
      setAnonymousId(aId);
    }

    getAnonymousId();
  }, []);

  const splitConfig: SplitIO.IBrowserSettings = {
    core: {
      authorizationKey: process.env.NEXT_PUBLIC_SPLIT_CLIENT_KEY as string,
      key: DUMMY_SPLIT_KEY,
      trafficType: "anonymous",
    },
  };

  if (anonymousId) {
    splitConfig.core.key = anonymousId;
  }

  return (
    <SplitFactoryProvider config={splitConfig}>
      <SplitClient splitKey={splitConfig.core.key}>{children}</SplitClient>
    </SplitFactoryProvider>
  );
};

When I log the isReady and client props i see that client is null when isReady is still false.
Does this mean i have to lazy load the SplitClient and my entire component tree that passes as children (render only when isReady === true)?

Or am I missing something in my setup?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions