Skip to content

Ability to change mode between SSR and CSR #1860

@theKashey

Description

@theKashey

This request is related to testing, not runtime. Especially testing in JSDOM environment

The problem is related to two moments:

  • isServerEnvironment is automatically picked for jsdom environment, however the "rendering model" is not compatible with RTL and can only be used for renderToString
  • if isServerEnvironment is somehow overriden, then Cache becomes global causing tests to pollute each other

Describe the solution you'd like

  • Ability to control isServerEnvironment
  • Ability to reset "clientside cache"

There is also an alternate solutions and basically what brought be here in the first place.

Consider the following code

export const useCache: UseCacheHook = () => {
  if (isCacheDisabled()) {
    return {};
  }

  if (isServerEnvironment()) {
    // On the server we use React Context to we don't leak the cache between SSR calls.
    // During runtime this hook isn't conditionally called - it is at build time that the flow gets decided.
    // eslint-disable-next-line react-hooks/rules-of-hooks
    return useContext(Cache) || {};
  }

  // On the client we use the object singleton.
  return Cache;
};

In some cases it will return an unique object, causing a new unique value to be provided to Cache.Provider and in turn cause performance regression for tests. A simple test can have a few hundreds of updates of this sort.

Adding CC around render breaks tests, as cache captures new elements, while rendered <styles>(renderToString solution) can be removed. This makes isServerEnvironment incompatible with JSDOM in general.

How this can be corrected

export const useCache: UseCacheHook = () => {
  if (isCacheDisabled()) {
    return {};
  }

  if (isServerEnvironment()) {
    // On the server we use React Context to we don't leak the cache between SSR calls.
    // During runtime this hook isn't conditionally called - it is at build time that the flow gets decided.
    // eslint-disable-next-line react-hooks/rules-of-hooks
    const stableValue = useMemo(() => ({}), []);
    // eslint-disable-next-line react-hooks/rules-of-hooks
    return useContext(Cache) || stableValue;
  }

  // On the client we use the object singleton.
  return Cache;
};

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions