Skip to content

Commit 355bd12

Browse files
authored
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 `<MyContext.Provider>` syntax and can be rendered as `<MyContext>` 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.
1 parent b81358c commit 355bd12

File tree

67 files changed

+226
-253
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+226
-253
lines changed

docs/custom-components/custom-providers.mdx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,19 @@ Then build your Custom Provider as follows:
2727

2828
```tsx
2929
'use client'
30-
import React, { createContext, useContext } from 'react'
30+
import React, { createContext, use } from 'react'
3131

3232
const MyCustomContext = React.createContext(myCustomValue)
3333

3434
export function MyProvider({ children }: { children: React.ReactNode }) {
3535
return (
36-
<MyCustomContext.Provider value={myCustomValue}>
36+
<MyCustomContext value={myCustomValue}>
3737
{children}
38-
</MyCustomContext.Provider>
38+
</MyCustomContext>
3939
)
4040
}
4141

42-
export const useMyCustomContext = () => useContext(MyCustomContext)
42+
export const useMyCustomContext = () => use(MyCustomContext)
4343
```
4444

4545
_For details on how to build Custom Components, see [Building Custom Components](./overview#building-custom-components)._

examples/auth/src/app/(app)/_providers/Auth/index.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import type { Permissions } from 'payload/auth'
44

5-
import React, { createContext, useCallback, useContext, useEffect, useState } from 'react'
5+
import React, { createContext, useCallback, use, useEffect, useState } from 'react'
66

77
import type { User } from '../../../../payload-types'
88
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
163163
)
164164

165165
return (
166-
<Context.Provider
166+
<Context
167167
value={{
168168
create,
169169
forgotPassword,
@@ -177,10 +177,10 @@ export const AuthProvider: React.FC<{ api?: 'gql' | 'rest'; children: React.Reac
177177
}}
178178
>
179179
{children}
180-
</Context.Provider>
180+
</Context>
181181
)
182182
}
183183

184-
type UseAuth<T = User> = () => AuthContext
184+
type UseAuth<T = User> = () => AuthContext
185185

186-
export const useAuth: UseAuth = () => useContext(Context)
186+
export const useAuth: UseAuth = () => use(Context)

examples/localization/src/providers/HeaderTheme/index.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import type { Theme } from '@/providers/Theme/types'
44

5-
import React, { createContext, useCallback, useContext, useState } from 'react'
5+
import React, { createContext, useCallback, use, useState } from 'react'
66

77
import canUseDOM from '@/utilities/canUseDOM'
88

@@ -27,11 +27,7 @@ export const HeaderThemeProvider = ({ children }: { children: React.ReactNode })
2727
setThemeState(themeToSet)
2828
}, [])
2929

30-
return (
31-
<HeaderThemeContext.Provider value={{ headerTheme, setHeaderTheme }}>
32-
{children}
33-
</HeaderThemeContext.Provider>
34-
)
30+
return <HeaderThemeContext value={{ headerTheme, setHeaderTheme }}>{children}</HeaderThemeContext>
3531
}
3632

37-
export const useHeaderTheme = (): ContextType => useContext(HeaderThemeContext)
33+
export const useHeaderTheme = (): ContextType => use(HeaderThemeContext)

examples/localization/src/providers/Theme/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client'
22

3-
import React, { createContext, useCallback, useContext, useEffect, useState } from 'react'
3+
import React, { createContext, useCallback, use, useEffect, useState } from 'react'
44

55
import type { Theme, ThemeContextType } from './types'
66

@@ -51,7 +51,7 @@ export const ThemeProvider = ({ children }: { children: React.ReactNode }) => {
5151
setThemeState(themeToSet)
5252
}, [])
5353

54-
return <ThemeContext.Provider value={{ setTheme, theme }}>{children}</ThemeContext.Provider>
54+
return <ThemeContext value={{ setTheme, theme }}>{children}</ThemeContext>
5555
}
5656

57-
export const useTheme = (): ThemeContextType => useContext(ThemeContext)
57+
export const useTheme = (): ThemeContextType => use(ThemeContext)

packages/next/src/views/LivePreview/Context/context.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { fieldSchemaToJSON } from 'payload/shared'
44
import type { Dispatch } from 'react'
55
import type React from 'react'
66

7-
import { createContext, useContext } from 'react'
7+
import { createContext, use } from 'react'
88

99
import type { usePopupWindow } from '../usePopupWindow.js'
1010
import type { SizeReducerAction } from './sizeReducer.js'
@@ -83,4 +83,4 @@ export const LivePreviewContext = createContext<LivePreviewContextType>({
8383
zoom: 1,
8484
})
8585

86-
export const useLivePreviewContext = () => useContext(LivePreviewContext)
86+
export const useLivePreviewContext = () => use(LivePreviewContext)

packages/next/src/views/LivePreview/Context/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ export const LivePreviewProvider: React.FC<LivePreviewProviderProps> = ({
166166
}, [previewWindowType, isPopupOpen, handleWindowChange])
167167

168168
return (
169-
<LivePreviewContext.Provider
169+
<LivePreviewContext
170170
value={{
171171
appIsReady,
172172
breakpoint,
@@ -198,6 +198,6 @@ export const LivePreviewProvider: React.FC<LivePreviewProviderProps> = ({
198198
<DndContext collisionDetection={customCollisionDetection} onDragEnd={handleDragEnd}>
199199
{listeningForMessages && children}
200200
</DndContext>
201-
</LivePreviewContext.Provider>
201+
</LivePreviewContext>
202202
)
203203
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client'
22

3-
import React, { createContext } from 'react'
3+
import { createContext, use } from 'react'
44

55
type SelectedLocalesContextType = {
66
selectedLocales: string[]
@@ -10,4 +10,4 @@ export const SelectedLocalesContext = createContext<SelectedLocalesContextType>(
1010
selectedLocales: [],
1111
})
1212

13-
export const useSelectedLocales = () => React.useContext(SelectedLocalesContext)
13+
export const useSelectedLocales = () => use(SelectedLocalesContext)

packages/next/src/views/Version/Default/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,11 @@ export const DefaultVersionView: React.FC<DefaultVersionsViewProps> = ({
182182
/>
183183
)}
184184
</div>
185-
<SelectedLocalesContext.Provider
185+
<SelectedLocalesContext
186186
value={{ selectedLocales: selectedLocales.map((locale) => locale.value) }}
187187
>
188188
{doc?.version && RenderedDiff}
189-
</SelectedLocalesContext.Provider>
189+
</SelectedLocalesContext>
190190
</Gutter>
191191
</main>
192192
)

packages/plugin-import-export/src/components/ImportExportProvider/index.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
'use client'
2-
import React, { createContext, useCallback, useContext, useState } from 'react'
2+
import React, { createContext, use, useCallback, useState } from 'react'
33

44
type ImportExportContext = {
55
collection: string
@@ -16,15 +16,15 @@ export const ImportExportProvider: React.FC<{ children: React.ReactNode }> = ({
1616
}, [])
1717

1818
return (
19-
<ImportExportContext.Provider
19+
<ImportExportContext
2020
value={{
2121
collection,
2222
setCollection,
2323
}}
2424
>
2525
{children}
26-
</ImportExportContext.Provider>
26+
</ImportExportContext>
2727
)
2828
}
2929

30-
export const useImportExport = (): ImportExportContext => useContext(ImportExportContext)
30+
export const useImportExport = (): ImportExportContext => use(ImportExportContext)

packages/richtext-lexical/src/features/blocks/client/component/BlockContent.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ const BlockComponentContext = createContext<BlockComponentContextType>({
4949
initialState: false,
5050
})
5151

52-
export const useBlockComponentContext = () => React.useContext(BlockComponentContext)
52+
export const useBlockComponentContext = () => React.use(BlockComponentContext)
5353

5454
/**
5555
* The actual content of the Block. This should be INSIDE a Form component,
@@ -99,7 +99,7 @@ export const BlockContent: React.FC<Props> = (props) => {
9999
)
100100

101101
return CustomBlock ? (
102-
<BlockComponentContext.Provider
102+
<BlockComponentContext
103103
value={{
104104
BlockCollapsible: CollapsibleWithErrorProps,
105105
EditButton,
@@ -110,7 +110,7 @@ export const BlockContent: React.FC<Props> = (props) => {
110110
>
111111
{CustomBlock}
112112
<BlockDrawer />
113-
</BlockComponentContext.Provider>
113+
</BlockComponentContext>
114114
) : (
115115
<CollapsibleWithErrorProps>
116116
<RenderFields

0 commit comments

Comments
 (0)