Skip to content

Commit e5bf65a

Browse files
committed
Fix Create, Edit and Show cannot be used outside of a ResourceContextProvider
Closes #5662
1 parent a25dced commit e5bf65a

File tree

4 files changed

+61
-24
lines changed

4 files changed

+61
-24
lines changed

packages/ra-core/src/core/useResourceContext.ts

+30-20
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,42 @@ import { ResourceContext, ResourceContextValue } from './ResourceContext';
55
* Hook to read the resource from the ResourceContext.
66
*
77
* Must be used within a <ResourceContextProvider> (e.g. as a descendent of <Resource>
8-
* or any reference related components).
8+
* or any reference related components), or called with a resource prop.
99
*
10-
* @returns {ResourceContextValue} The resource
10+
* @example
11+
*
12+
* const ResourceName = (props) => {
13+
* const { resource } = useResourceContext(props);
14+
* const resourceName = translate(`resources.${resource}.name`, {
15+
* smart_count: 1,
16+
* _: inflection.humanize(inflection.singularize(resource)),
17+
* });
18+
* return <>{resourceName}</>;
19+
* }
20+
*
21+
* // use it in a resource context
22+
* const MyComponent = () => (
23+
* <ResourceContextProvider value="posts">
24+
* <ResourceName />
25+
* ...
26+
* </ResourceContextProvider>
27+
* );
28+
*
29+
* // override resource via props
30+
* const MyComponent = () => (
31+
* <>
32+
* <ResourceName resource="posts"/>
33+
* ...
34+
* </>
35+
* );
36+
*
37+
* @returns {ResourceContextValue} The resource name, e.g. 'posts'
1138
*/
1239
export const useResourceContext = <
1340
ResourceInformationsType extends Partial<{ resource: string }>
1441
>(
1542
props: ResourceInformationsType
1643
): ResourceContextValue => {
1744
const context = useContext(ResourceContext);
18-
19-
if (!context) {
20-
/**
21-
* The element isn't inside a <ResourceContextProvider>
22-
*
23-
* @deprecated - to be removed in 4.0
24-
*/
25-
if (process.env.NODE_ENV !== 'production') {
26-
// Restore this message when ResourceContext is actually used
27-
// console.warn(
28-
// "Any react-admin components must be used inside a <ResourceContextProvider>. Relying on props rather than context to get the resource data is deprecated and won't be supported in the next major version of react-admin."
29-
// );
30-
}
31-
// Ignored because resource is often optional (as it is injected) in components which passes the props to this hook
32-
return props.resource;
33-
}
34-
35-
return context;
45+
return props.resource || context;
3646
};

packages/ra-ui-materialui/src/detail/Create.tsx

+11-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { ReactElement } from 'react';
33
import PropTypes from 'prop-types';
44
import {
55
CreateContextProvider,
6+
ResourceContextProvider,
67
useCheckMinimumRequiredProps,
78
useCreateController,
89
} from 'ra-core';
@@ -58,11 +59,19 @@ export const Create = (
5859
): ReactElement => {
5960
useCheckMinimumRequiredProps('Create', ['children'], props);
6061
const controllerProps = useCreateController(props);
61-
return (
62+
const body = (
6263
<CreateContextProvider value={controllerProps}>
6364
<CreateView {...props} {...controllerProps} />
6465
</CreateContextProvider>
6566
);
67+
return props.resource ? (
68+
// support resource override via props
69+
<ResourceContextProvider value={props.resource}>
70+
{body}
71+
</ResourceContextProvider>
72+
) : (
73+
body
74+
);
6675
};
6776

6877
Create.propTypes = {
@@ -74,7 +83,7 @@ Create.propTypes = {
7483
hasCreate: PropTypes.bool,
7584
hasEdit: PropTypes.bool,
7685
hasShow: PropTypes.bool,
77-
resource: PropTypes.string.isRequired,
86+
resource: PropTypes.string,
7887
title: PropTypes.node,
7988
record: PropTypes.object,
8089
hasList: PropTypes.bool,

packages/ra-ui-materialui/src/detail/Edit.tsx

+10-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { ReactElement } from 'react';
33
import PropTypes from 'prop-types';
44
import {
55
EditContextProvider,
6+
ResourceContextProvider,
67
useCheckMinimumRequiredProps,
78
useEditController,
89
} from 'ra-core';
@@ -59,11 +60,19 @@ export const Edit = (
5960
): ReactElement => {
6061
useCheckMinimumRequiredProps('Edit', ['children'], props);
6162
const controllerProps = useEditController(props);
62-
return (
63+
const body = (
6364
<EditContextProvider value={controllerProps}>
6465
<EditView {...props} {...controllerProps} />
6566
</EditContextProvider>
6667
);
68+
return props.resource ? (
69+
// support resource override via props
70+
<ResourceContextProvider value={props.resource}>
71+
{body}
72+
</ResourceContextProvider>
73+
) : (
74+
body
75+
);
6776
};
6877

6978
Edit.propTypes = {

packages/ra-ui-materialui/src/detail/Show.tsx

+10-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { ReactElement } from 'react';
33
import PropTypes from 'prop-types';
44
import {
55
ShowContextProvider,
6+
ResourceContextProvider,
67
useCheckMinimumRequiredProps,
78
useShowController,
89
} from 'ra-core';
@@ -58,11 +59,19 @@ export const Show = (
5859
): ReactElement => {
5960
useCheckMinimumRequiredProps('Show', ['children'], props);
6061
const controllerProps = useShowController(props);
61-
return (
62+
const body = (
6263
<ShowContextProvider value={controllerProps}>
6364
<ShowView {...props} {...controllerProps} />
6465
</ShowContextProvider>
6566
);
67+
return props.resource ? (
68+
// support resource override via props
69+
<ResourceContextProvider value={props.resource}>
70+
{body}
71+
</ResourceContextProvider>
72+
) : (
73+
body
74+
);
6675
};
6776

6877
Show.propTypes = {

0 commit comments

Comments
 (0)