diff --git a/packages/ra-core/src/controller/RecordContext.tsx b/packages/ra-core/src/controller/RecordContext.tsx index 4fd1885f7a7..32620adf2b4 100644 --- a/packages/ra-core/src/controller/RecordContext.tsx +++ b/packages/ra-core/src/controller/RecordContext.tsx @@ -1,6 +1,5 @@ import * as React from 'react'; -import { createContext, ReactNode, useContext, useMemo } from 'react'; -import pick from 'lodash/pick'; +import { createContext, ReactNode, useContext } from 'react'; import { Record } from '../types'; /** @@ -13,7 +12,7 @@ import { Record } from '../types'; * import { useEditController, EditContext } from 'ra-core'; * * const Edit = props => { - * const { record }= useEditController(props); + * const { record } = useEditController(props); * return ( * * ... @@ -25,22 +24,21 @@ export const RecordContext = createContext>( undefined ); -export const RecordContextProvider = ({ +export const RecordContextProvider = < + RecordType extends Record | Omit = Record +>({ children, value, -}: RecordContextOptions) => ( +}: RecordContextOptions) => ( {children} ); + RecordContext.displayName = 'RecordContext'; -export const usePickRecordContext = < - RecordType extends Record | Omit = Record ->( - context: RecordType -) => { - const value = useMemo(() => pick(context, ['record']), [context.record]); // eslint-disable-line - return value; -}; +export interface RecordContextOptions { + children: ReactNode; + value?: RecordType; +} /** * Hook to read the record from a RecordContext. @@ -49,30 +47,42 @@ export const usePickRecordContext = < * (e.g. as a descendent of or ) or within a * (e.g. as a descendent of or ) * - * @returns {Record} The record context + * @example // basic usage + * + * import { useRecordContext } from 'ra-core'; + * + * const TitleField = () => { + * const record = useRecordContext(); + * return {record && record.title}; + * }; + * + * @example // allow record override via props + * + * import { useRecordContext } from 'ra-core'; + * + * const TitleField = (props) => { + * const record = useRecordContext(props); + * return {record && record.title}; + * }; + * render(); + * + * @returns {Record} A record object */ export const useRecordContext = < RecordType extends Record | Omit = Record >( - props: RecordType + props: UseRecordContextParams ): RecordType => { // Can't find a way to specify the RecordType when CreateContext is declared // @ts-ignore const context = useContext(RecordContext); - if (!context) { - // As the record could very well be undefined because not yet loaded - // We don't display a deprecation warning yet - // @deprecated - to be removed in 4.0 - return props; - } - - return context; + return (props && props.record) || context; }; -export interface RecordContextOptions< +export interface UseRecordContextParams< RecordType extends Record | Omit = Record > { - children: ReactNode; - value?: RecordType; + record?: RecordType; + [key: string]: any; } diff --git a/packages/ra-core/src/controller/details/CreateContextProvider.tsx b/packages/ra-core/src/controller/details/CreateContextProvider.tsx index e85b01e7044..3a8a58494b8 100644 --- a/packages/ra-core/src/controller/details/CreateContextProvider.tsx +++ b/packages/ra-core/src/controller/details/CreateContextProvider.tsx @@ -1,9 +1,10 @@ import * as React from 'react'; import { ReactElement } from 'react'; -import { RecordContextProvider, usePickRecordContext } from '../RecordContext'; +import { RecordContextProvider } from '../RecordContext'; import { CreateContext } from './CreateContext'; import { CreateControllerProps } from './useCreateController'; import { SaveContextProvider, usePickSaveContext } from './SaveContext'; +import { Record } from '../../types'; /** * Create a Create Context. @@ -37,7 +38,9 @@ export const CreateContextProvider = ({ }) => ( - + > + value={value && value.record} + > {children} diff --git a/packages/ra-core/src/controller/details/EditContextProvider.tsx b/packages/ra-core/src/controller/details/EditContextProvider.tsx index 94e4cd14a1f..20095a42a7f 100644 --- a/packages/ra-core/src/controller/details/EditContextProvider.tsx +++ b/packages/ra-core/src/controller/details/EditContextProvider.tsx @@ -1,9 +1,10 @@ import * as React from 'react'; import { ReactElement } from 'react'; -import { RecordContextProvider, usePickRecordContext } from '../RecordContext'; +import { RecordContextProvider } from '../RecordContext'; import { EditContext } from './EditContext'; import { EditControllerProps } from './useEditController'; import { SaveContextProvider, usePickSaveContext } from './SaveContext'; +import { Record } from '../../types'; /** * Create an Edit Context. @@ -37,7 +38,9 @@ export const EditContextProvider = ({ }) => ( - + > + value={value && value.record} + > {children} diff --git a/packages/ra-core/src/controller/details/ShowContextProvider.tsx b/packages/ra-core/src/controller/details/ShowContextProvider.tsx index 871b4683243..c4d0bb9be03 100644 --- a/packages/ra-core/src/controller/details/ShowContextProvider.tsx +++ b/packages/ra-core/src/controller/details/ShowContextProvider.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import { ReactElement } from 'react'; -import { RecordContextProvider, usePickRecordContext } from '../RecordContext'; +import { Record } from '../../types'; +import { RecordContextProvider } from '../RecordContext'; import { ShowContext } from './ShowContext'; import { ShowControllerProps } from './useShowController'; @@ -33,7 +34,7 @@ export const ShowContextProvider = ({ value: ShowControllerProps; }) => ( - + > value={value && value.record}> {children}