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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions