config-context.ts


Overview

The config-context.ts file implements a React context provider component (SWRConfig) that manages configuration settings for the SWR (stale-while-revalidate) data fetching library. It enables scoped or global configuration management through React’s context API, allowing SWR hooks in the component tree to consume unified or layered configuration options seamlessly.

This file handles:

By centralizing configuration in this manner, the file allows flexible, composable, and dynamic configuration of SWR hooks in React applications, supporting advanced features like custom cache providers and middleware enhancements.


Detailed Explanations

SWRConfigContext

export const SWRConfigContext = createContext<Partial<FullConfiguration>>({})

SWRConfig Component

const SWRConfig: FC<
  PropsWithChildren<{
    value?:
      | SWRConfiguration
      | ((parentConfig?: SWRConfiguration) => SWRConfiguration)
  }>
> = props => { ... }

Parameters

Parameter

Type

Description

props.value

`SWRConfiguration \

(parentConfig?: SWRConfiguration) => SWRConfiguration`

props.children

React.ReactNode

Child components wrapped by this provider.


Functionality & Workflow

  1. Consume Parent Configuration:

    Uses useContext(SWRConfigContext) to obtain the nearest parent configuration.

  2. Resolve Current Configuration:

    • Checks if value prop is a function (isFunction(value)).

    • If a function, calls it with parentConfig to get current config.

    • Otherwise, uses the value directly.

  3. Merge Configurations:

    • If value is a function, the returned config replaces or extends the parent config.

    • If value is an object, merges it with parentConfig using mergeConfigs.

  4. Cache Provider Initialization:

    • Checks if the provider property is set in the current config.

    • If yes, initializes a cache context using initCache with the provided cache and config.

    • Uses useRef to ensure cache initialization happens only once.

  5. Cache and Mutate Override:

    • If a cache context exists, overrides cache and mutate in the extended config with values from the cache context.

  6. Lifecycle Cleanup:

    • Uses useIsomorphicLayoutEffect to unsubscribe from cache events on unmount to avoid memory leaks.

  7. Provide Context:

    • Returns a SWRConfigContext.Provider element that wraps props.children.

    • Passes the fully merged and extended config as the context value.


Return Value


Usage Example

import SWRConfig from './config-context'

function App() {
  const globalConfig = {
    refreshInterval: 3000,
    fetcher: (url: string) => fetch(url).then(res => res.json()),
  }

  return (
    <SWRConfig value={globalConfig}>
      <MyComponent />
    </SWRConfig>
  )
}

In this example, MyComponent and all its descendants will consume the globalConfig via the SWR context.


Important Implementation Details


Interaction with Other Parts of the System


Mermaid Diagram

classDiagram
    class SWRConfigContext {
        <<React Context>>
        +Partial<FullConfiguration> value
    }

    class SWRConfig {
        +value?: SWRConfiguration | (parentConfig?: SWRConfiguration) => SWRConfiguration
        +children: ReactNode
        -parentConfig: Partial<FullConfiguration>
        -config: SWRConfiguration
        -extendedConfig: SWRConfiguration
        -cacheContextRef: React.RefObject
        +render(): JSX.Element
    }

    SWRConfig --> SWRConfigContext : provides
    SWRConfig o-- "1" initCache : initializes cache via
    SWRConfig --> useContext : reads parentConfig
    SWRConfig --> useMemo : memoizes merged configs
    SWRConfig --> useIsomorphicLayoutEffect : manages lifecycle cleanup

Summary

The config-context.ts file is a pivotal part of the SWR library’s configuration management system. It defines a context provider component that allows React applications to specify and inherit SWR configurations in a composable and dynamic way. It supports merging configurations, injecting custom cache providers, managing lifecycle cleanup, and enabling middleware composition. This design enables robust, flexible, and scalable data fetching configurations across complex React component trees.