From 355bd12c6152341d80b1c25e60423eed5222b1c4 Mon Sep 17 00:00:00 2001 From: Jacob Fletcher Date: Wed, 12 Mar 2025 15:48:20 -0400 Subject: [PATCH] chore: infer React context providers and prefer use (#11669) As of [React 19](https://react.dev/blog/2024/12/05/react-19), context providers no longer require the `` syntax and can be rendered as `` directly. This will be deprecated in future versions of React, which is now being caught by the [`@eslint-react/no-context-provider`](https://eslint-react.xyz/docs/rules/no-context-provider) ESLint rule. Similarly, the [`use`](https://react.dev/reference/react/use) API is now preferred over `useContext` because it is more flexible, for example they can be called within loops and conditional statements. See the [`@eslint-react/no-use-context`](https://eslint-react.xyz/docs/rules/no-use-context) ESLint rule for more details. --- docs/custom-components/custom-providers.mdx | 8 ++--- .../src/app/(app)/_providers/Auth/index.tsx | 10 +++--- .../src/providers/HeaderTheme/index.tsx | 10 ++---- .../src/providers/Theme/index.tsx | 6 ++-- .../src/views/LivePreview/Context/context.ts | 4 +-- .../src/views/LivePreview/Context/index.tsx | 4 +-- .../Default/SelectedLocalesContext.tsx | 4 +-- .../next/src/views/Version/Default/index.tsx | 4 +-- .../components/ImportExportProvider/index.tsx | 8 ++--- .../blocks/client/component/BlockContent.tsx | 6 ++-- .../blocks/client/componentInline/index.tsx | 6 ++-- .../client/plugins/TablePlugin/index.tsx | 8 ++--- .../shared/ToolbarDropdown/DropDown.tsx | 6 ++-- .../config/client/EditorConfigProvider.tsx | 6 ++-- .../field/providers/ElementButtonProvider.tsx | 6 ++-- .../src/field/providers/ElementProvider.tsx | 6 ++-- .../field/providers/LeafButtonProvider.tsx | 6 ++-- .../src/field/providers/LeafProvider.tsx | 6 ++-- .../src/utilities/SlatePropsProvider.tsx | 6 ++-- .../BulkUpload/FormsManager/index.tsx | 6 ++-- packages/ui/src/elements/BulkUpload/index.tsx | 6 ++-- .../ui/src/elements/Collapsible/provider.tsx | 6 ++-- .../src/elements/DocumentDrawer/Provider.tsx | 10 ++---- packages/ui/src/elements/Drawer/index.tsx | 6 ++-- .../src/elements/EditMany/DrawerContent.tsx | 4 +-- .../ui/src/elements/ListDrawer/Provider.tsx | 8 ++--- .../ui/src/elements/LoadingOverlay/index.tsx | 6 ++-- packages/ui/src/elements/Nav/context.tsx | 6 ++-- packages/ui/src/elements/StepNav/context.tsx | 8 ++--- .../Table/RelationshipProvider/index.tsx | 6 ++-- .../TableColumns/RenderDefaultCell/index.tsx | 6 ++-- .../ui/src/elements/TableColumns/context.ts | 4 +-- .../ui/src/elements/TableColumns/index.tsx | 4 +-- packages/ui/src/fields/Group/provider.tsx | 6 ++-- packages/ui/src/fields/Row/provider.tsx | 6 ++-- packages/ui/src/fields/Tabs/provider.tsx | 6 ++-- packages/ui/src/forms/Form/context.ts | 18 +++++------ packages/ui/src/forms/Form/index.tsx | 31 ++++++++++--------- .../ui/src/forms/RowLabel/Context/index.tsx | 4 +-- packages/ui/src/providers/Actions/index.tsx | 8 ++--- packages/ui/src/providers/Auth/index.tsx | 8 ++--- .../ui/src/providers/ClientFunction/index.tsx | 12 +++---- packages/ui/src/providers/Config/index.tsx | 8 ++--- .../ui/src/providers/DocumentEvents/index.tsx | 6 ++-- .../ui/src/providers/DocumentInfo/index.tsx | 6 ++-- packages/ui/src/providers/EditDepth/index.tsx | 6 ++-- .../src/providers/EntityVisibility/index.tsx | 8 ++--- .../ui/src/providers/ListQuery/context.ts | 4 +-- packages/ui/src/providers/ListQuery/index.tsx | 4 +-- packages/ui/src/providers/Locale/index.tsx | 14 ++++----- packages/ui/src/providers/Operation/index.tsx | 6 ++-- packages/ui/src/providers/Params/index.tsx | 6 ++-- .../ui/src/providers/Preferences/index.tsx | 6 ++-- .../ui/src/providers/RouteCache/index.tsx | 6 ++-- .../src/providers/RouteTransition/index.tsx | 8 ++--- .../ui/src/providers/SearchParams/index.tsx | 6 ++-- packages/ui/src/providers/Selection/index.tsx | 6 ++-- .../src/providers/ServerFunctions/index.tsx | 6 ++-- packages/ui/src/providers/Theme/index.tsx | 6 ++-- .../ui/src/providers/Translation/index.tsx | 8 ++--- .../ui/src/providers/UploadEdits/index.tsx | 8 ++--- .../ui/src/providers/UploadHandlers/index.tsx | 6 ++-- .../src/providers/HeaderTheme/index.tsx | 10 ++---- .../website/src/providers/Theme/index.tsx | 6 ++-- .../src/providers/HeaderTheme/index.tsx | 10 ++---- .../src/providers/Theme/index.tsx | 6 ++-- .../admin/components/CustomProvider/index.tsx | 8 ++--- 67 files changed, 226 insertions(+), 253 deletions(-) diff --git a/docs/custom-components/custom-providers.mdx b/docs/custom-components/custom-providers.mdx index d3e532162..26abe74fd 100644 --- a/docs/custom-components/custom-providers.mdx +++ b/docs/custom-components/custom-providers.mdx @@ -27,19 +27,19 @@ Then build your Custom Provider as follows: ```tsx 'use client' -import React, { createContext, useContext } from 'react' +import React, { createContext, use } from 'react' const MyCustomContext = React.createContext(myCustomValue) export function MyProvider({ children }: { children: React.ReactNode }) { return ( - + {children} - + ) } -export const useMyCustomContext = () => useContext(MyCustomContext) +export const useMyCustomContext = () => use(MyCustomContext) ``` _For details on how to build Custom Components, see [Building Custom Components](./overview#building-custom-components)._ diff --git a/examples/auth/src/app/(app)/_providers/Auth/index.tsx b/examples/auth/src/app/(app)/_providers/Auth/index.tsx index 6083705c5..78da1ea56 100644 --- a/examples/auth/src/app/(app)/_providers/Auth/index.tsx +++ b/examples/auth/src/app/(app)/_providers/Auth/index.tsx @@ -2,7 +2,7 @@ import type { Permissions } from 'payload/auth' -import React, { createContext, useCallback, useContext, useEffect, useState } from 'react' +import React, { createContext, useCallback, use, useEffect, useState } from 'react' import type { User } from '../../../../payload-types' import type { AuthContext, Create, ForgotPassword, Login, Logout, ResetPassword } from './types' @@ -163,7 +163,7 @@ export const AuthProvider: React.FC<{ api?: 'gql' | 'rest'; children: React.Reac ) return ( - {children} - + ) } -type UseAuth = () => AuthContext +type UseAuth = () => AuthContext -export const useAuth: UseAuth = () => useContext(Context) +export const useAuth: UseAuth = () => use(Context) diff --git a/examples/localization/src/providers/HeaderTheme/index.tsx b/examples/localization/src/providers/HeaderTheme/index.tsx index 76666f101..1d0255787 100644 --- a/examples/localization/src/providers/HeaderTheme/index.tsx +++ b/examples/localization/src/providers/HeaderTheme/index.tsx @@ -2,7 +2,7 @@ import type { Theme } from '@/providers/Theme/types' -import React, { createContext, useCallback, useContext, useState } from 'react' +import React, { createContext, useCallback, use, useState } from 'react' import canUseDOM from '@/utilities/canUseDOM' @@ -27,11 +27,7 @@ export const HeaderThemeProvider = ({ children }: { children: React.ReactNode }) setThemeState(themeToSet) }, []) - return ( - - {children} - - ) + return {children} } -export const useHeaderTheme = (): ContextType => useContext(HeaderThemeContext) +export const useHeaderTheme = (): ContextType => use(HeaderThemeContext) diff --git a/examples/localization/src/providers/Theme/index.tsx b/examples/localization/src/providers/Theme/index.tsx index 882d8318d..60dcedca4 100644 --- a/examples/localization/src/providers/Theme/index.tsx +++ b/examples/localization/src/providers/Theme/index.tsx @@ -1,6 +1,6 @@ 'use client' -import React, { createContext, useCallback, useContext, useEffect, useState } from 'react' +import React, { createContext, useCallback, use, useEffect, useState } from 'react' import type { Theme, ThemeContextType } from './types' @@ -51,7 +51,7 @@ export const ThemeProvider = ({ children }: { children: React.ReactNode }) => { setThemeState(themeToSet) }, []) - return {children} + return {children} } -export const useTheme = (): ThemeContextType => useContext(ThemeContext) +export const useTheme = (): ThemeContextType => use(ThemeContext) diff --git a/packages/next/src/views/LivePreview/Context/context.ts b/packages/next/src/views/LivePreview/Context/context.ts index 236bc419a..a35d6dbe7 100644 --- a/packages/next/src/views/LivePreview/Context/context.ts +++ b/packages/next/src/views/LivePreview/Context/context.ts @@ -4,7 +4,7 @@ import type { fieldSchemaToJSON } from 'payload/shared' import type { Dispatch } from 'react' import type React from 'react' -import { createContext, useContext } from 'react' +import { createContext, use } from 'react' import type { usePopupWindow } from '../usePopupWindow.js' import type { SizeReducerAction } from './sizeReducer.js' @@ -83,4 +83,4 @@ export const LivePreviewContext = createContext({ zoom: 1, }) -export const useLivePreviewContext = () => useContext(LivePreviewContext) +export const useLivePreviewContext = () => use(LivePreviewContext) diff --git a/packages/next/src/views/LivePreview/Context/index.tsx b/packages/next/src/views/LivePreview/Context/index.tsx index 3ea06d3cb..7878d3c44 100644 --- a/packages/next/src/views/LivePreview/Context/index.tsx +++ b/packages/next/src/views/LivePreview/Context/index.tsx @@ -166,7 +166,7 @@ export const LivePreviewProvider: React.FC = ({ }, [previewWindowType, isPopupOpen, handleWindowChange]) return ( - = ({ {listeningForMessages && children} - + ) } diff --git a/packages/next/src/views/Version/Default/SelectedLocalesContext.tsx b/packages/next/src/views/Version/Default/SelectedLocalesContext.tsx index 484b6a64d..2913b82a6 100644 --- a/packages/next/src/views/Version/Default/SelectedLocalesContext.tsx +++ b/packages/next/src/views/Version/Default/SelectedLocalesContext.tsx @@ -1,6 +1,6 @@ 'use client' -import React, { createContext } from 'react' +import { createContext, use } from 'react' type SelectedLocalesContextType = { selectedLocales: string[] @@ -10,4 +10,4 @@ export const SelectedLocalesContext = createContext( selectedLocales: [], }) -export const useSelectedLocales = () => React.useContext(SelectedLocalesContext) +export const useSelectedLocales = () => use(SelectedLocalesContext) diff --git a/packages/next/src/views/Version/Default/index.tsx b/packages/next/src/views/Version/Default/index.tsx index d25dfb926..034243c3d 100644 --- a/packages/next/src/views/Version/Default/index.tsx +++ b/packages/next/src/views/Version/Default/index.tsx @@ -182,11 +182,11 @@ export const DefaultVersionView: React.FC = ({ /> )} - locale.value) }} > {doc?.version && RenderedDiff} - + ) diff --git a/packages/plugin-import-export/src/components/ImportExportProvider/index.tsx b/packages/plugin-import-export/src/components/ImportExportProvider/index.tsx index fc4c4d03f..185708f8f 100644 --- a/packages/plugin-import-export/src/components/ImportExportProvider/index.tsx +++ b/packages/plugin-import-export/src/components/ImportExportProvider/index.tsx @@ -1,5 +1,5 @@ 'use client' -import React, { createContext, useCallback, useContext, useState } from 'react' +import React, { createContext, use, useCallback, useState } from 'react' type ImportExportContext = { collection: string @@ -16,15 +16,15 @@ export const ImportExportProvider: React.FC<{ children: React.ReactNode }> = ({ }, []) return ( - {children} - + ) } -export const useImportExport = (): ImportExportContext => useContext(ImportExportContext) +export const useImportExport = (): ImportExportContext => use(ImportExportContext) diff --git a/packages/richtext-lexical/src/features/blocks/client/component/BlockContent.tsx b/packages/richtext-lexical/src/features/blocks/client/component/BlockContent.tsx index 471bd137e..5f25764d1 100644 --- a/packages/richtext-lexical/src/features/blocks/client/component/BlockContent.tsx +++ b/packages/richtext-lexical/src/features/blocks/client/component/BlockContent.tsx @@ -49,7 +49,7 @@ const BlockComponentContext = createContext({ initialState: false, }) -export const useBlockComponentContext = () => React.useContext(BlockComponentContext) +export const useBlockComponentContext = () => React.use(BlockComponentContext) /** * The actual content of the Block. This should be INSIDE a Form component, @@ -99,7 +99,7 @@ export const BlockContent: React.FC = (props) => { ) return CustomBlock ? ( - = (props) => { > {CustomBlock} - + ) : ( React.useContext(InlineBlockComponentContext) +export const useInlineBlockComponentContext = () => React.use(InlineBlockComponentContext) export const InlineBlockComponent: React.FC = (props) => { const { cacheBuster, formData, nodeKey } = props @@ -426,7 +426,7 @@ export const InlineBlockComponent: React.FC = (props) => { {CustomBlock ? ( - = (props) => { }} > {CustomBlock} - + ) : ( {initialState ?