Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(poc): react19 & compiler #20314

Draft
wants to merge 1 commit into
base: v5/main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
"@mdx-js/react": "^3.0.0",
"clsx": "^1.1.1",
"prism-react-renderer": "^2.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react": "rc",
"react-dom": "rc"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "3.1.1",
Expand Down
4 changes: 2 additions & 2 deletions examples/getstarted/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
"mysql2": "3.6.2",
"passport-google-oauth2": "0.2.0",
"pg": "8.11.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react": "rc",
"react-dom": "rc",
"react-intl": "6.6.2",
"react-router-dom": "6.22.3",
"strapi-plugin-workspace-plugin": "workspace:*",
Expand Down
4 changes: 2 additions & 2 deletions examples/kitchensink-ts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
"@strapi/plugin-users-permissions": "5.0.0-beta.7",
"@strapi/strapi": "5.0.0-beta.7",
"better-sqlite3": "9.4.3",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react": "rc",
"react-dom": "rc",
"react-router-dom": "6.22.3",
"styled-components": "6.1.8"
},
Expand Down
4 changes: 2 additions & 2 deletions examples/kitchensink/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
"mysql2": "3.6.2",
"passport-google-oauth2": "0.2.0",
"pg": "8.11.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react": "rc",
"react-dom": "rc",
"react-router-dom": "6.22.3",
"styled-components": "6.1.8"
},
Expand Down
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@
"test:unit:watch": "run test:unit --watch"
},
"resolutions": {
"@types/koa": "2.13.4"
"@types/koa": "2.13.4",
"@types/react": "npm:types-react@beta",
"@types/react-dom": "npm:types-react-dom@beta"
},
"devDependencies": {
"@babel/core": "^7.20.12",
Expand All @@ -94,9 +96,8 @@
"@types/fs-extra": "11.0.4",
"@types/git-url-parse": "9.0.3",
"@types/prompts": "2.4.9",
"@types/react": "18.2.66",
"@types/react-dom": "18.2.22",
"@types/styled-components": "5.1.34",
"@types/react": "npm:types-react@beta",
"@types/react-dom": "npm:types-react-dom@beta",
"@typescript-eslint/eslint-plugin": "6.7.3",
"@typescript-eslint/parser": "6.7.3",
"babel-eslint": "10.1.0",
Expand All @@ -119,6 +120,7 @@
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-compiler": "0.0.0-experimental-53bb89e-20240515",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-rxjs": "5.0.3",
"eslint-plugin-testing-library": "6.0.2",
Expand Down
1 change: 0 additions & 1 deletion packages/core/admin/admin/src/components/Context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ function createContext<ContextValueType extends object | null>(
const Provider = (props: ContextValueType & { children: React.ReactNode }) => {
const { children, ...context } = props;
// Only re-memoize when prop values change
// eslint-disable-next-line react-hooks/exhaustive-deps
const value = React.useMemo(() => context, Object.values(context)) as ContextValueType;
return <Context.Provider value={value}>{children}</Context.Provider>;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ const DescriptionComponentRenderer = <Props, Description>({
* the `ids` will most likely be stable unless we get new actions, but we can't respond to the Description
* Component changing the ref data in any other way.
*/
// eslint-disable-next-line react-hooks/exhaustive-deps
[ids, tick]
);

Expand Down Expand Up @@ -175,7 +174,6 @@ const useShallowCompareMemoize = <T,>(value: T): Array<T | undefined> => {
};

const useShallowCompareEffect = (callback: React.EffectCallback, dependencies?: unknown) => {
// eslint-disable-next-line react-hooks/exhaustive-deps -- the linter isn't able to see that deps are properly handled here
React.useEffect(callback, useShallowCompareMemoize(dependencies));
};

Expand Down
2 changes: 1 addition & 1 deletion packages/core/admin/admin/src/components/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ const Form = React.forwardRef<HTMLFormElement, FormProps>(
}
) as <TFormValues extends FormValues>(
p: FormProps<TFormValues> & { ref?: React.Ref<HTMLFormElement> }
) => React.ReactElement; // we've cast this because we need the generic to infer the type of the form values.
) => React.ReactElement<any>; // we've cast this because we need the generic to infer the type of the form values.

/**
* @internal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ HeaderLayout.displayName = 'HeaderLayout';
*/
const useElementOnScreen = <TElement extends HTMLElement = HTMLElement>(
options?: IntersectionObserverInit
): [containerRef: React.RefObject<TElement>, isVisible: boolean] => {
const containerRef = React.useRef<TElement>(null);
): [containerRef: React.RefObject<TElement | null>, isVisible: boolean] => {
const containerRef = React.useRef<TElement | null>(null);

const [isVisible, setIsVisible] = React.useState<boolean>(true);

Expand All @@ -153,7 +153,7 @@ const useElementOnScreen = <TElement extends HTMLElement = HTMLElement>(
const observer = new IntersectionObserver(callback, options);

if (containerEl) {
observer.observe(containerRef.current);
observer.observe(containerRef.current as TElement);
}

return () => {
Expand All @@ -170,7 +170,7 @@ const useElementOnScreen = <TElement extends HTMLElement = HTMLElement>(
* useResizeObserver: hook that observes the size of an element and calls a callback when it changes.
*/
const useResizeObserver = (
sources: React.RefObject<HTMLElement> | React.RefObject<HTMLElement>[],
sources: React.RefObject<HTMLElement | null> | React.RefObject<HTMLElement | null>[],
onResize: ResizeObserverCallback
) => {
const handleResize = useCallbackRef(onResize);
Expand Down
42 changes: 19 additions & 23 deletions packages/core/admin/admin/src/components/PluginsInitializer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,10 @@ import { StrapiAppContextValue, useStrapiApp } from '../features/StrapiApp';
*/
const PluginsInitializer = ({ children }: { children: React.ReactNode }) => {
const appPlugins = useStrapiApp('PluginsInitializer', (state) => state.plugins);
const [{ plugins }, dispatch] = React.useReducer<React.Reducer<State, Action>, State>(
reducer,
initialState,
() => init(appPlugins)
);
const setPlugin = React.useRef((pluginId: string) => {
const [{ plugins }, dispatch] = React.useReducer(reducer, initialState, () => init(appPlugins));
const setPlugin = React.useCallback((pluginId: string) => {
dispatch({ type: 'SET_PLUGIN_READY', pluginId });
});
}, []);

const hasApluginNotReady = Object.keys(plugins).some(
(plugin) => plugins[plugin].isReady === false
Expand Down Expand Up @@ -47,26 +43,26 @@ const PluginsInitializer = ({ children }: { children: React.ReactNode }) => {
*
*/

if (hasApluginNotReady) {
const initializers = Object.keys(plugins).reduce((acc, current) => {
const InitializerComponent = plugins[current].initializer;
// if (hasApluginNotReady) {
// const initializers = Object.keys(plugins).reduce((acc, current) => {
// const InitializerComponent = plugins[current].initializer;

if (InitializerComponent) {
const key = plugins[current].pluginId;
// if (InitializerComponent) {
// const key = plugins[current].pluginId;

acc.push(<InitializerComponent key={key} setPlugin={setPlugin.current} />);
}
// acc.push(<InitializerComponent key={key} setPlugin={setPlugin} />);
// }

return acc;
}, [] as React.ReactNode[]);
// return acc;
// }, [] as React.ReactNode[]);

return (
<>
{initializers}
<Page.Loading />
</>
);
}
// return (
// <>
// {initializers}
// <Page.Loading />
// </>
// );
// }

return children;
};
Expand Down
6 changes: 0 additions & 6 deletions packages/core/admin/admin/src/hooks/useOnce.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/core/admin/admin/src/hooks/usePrev.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useEffect, useRef } from 'react';

export const usePrev = <T>(value: T): T | undefined => {
const ref = useRef<T>();
const ref = useRef<T>(undefined);

useEffect(() => {
ref.current = value;
Expand Down
5 changes: 2 additions & 3 deletions packages/core/admin/admin/src/layouts/AuthenticatedLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import { useAuth } from '../features/Auth';
import { useConfiguration } from '../features/Configuration';
import { useTracking } from '../features/Tracking';
import { useMenu } from '../hooks/useMenu';
import { useOnce } from '../hooks/useOnce';
import { useInformationQuery } from '../services/admin';
import { hashAdminUserEmail } from '../utils/users';

Expand Down Expand Up @@ -100,9 +99,9 @@ const AdminLayout = () => {
* and not at runtime for example when regenerating the permissions with the ctb
* or with i18n
*/
useOnce(() => {
React.useEffect(() => {
trackUsage('didAccessAuthenticatedAdministration');
});
}, [trackUsage]);

// We don't need to wait for the release query to be fetched before rendering the plugins
// however, we need the appInfos and the permissions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useIntl } from 'react-intl';
import { NavLink, useNavigate, Navigate, useLocation } from 'react-router-dom';
import * as yup from 'yup';

import { ResetPassword } from '../../../../../shared/contracts/authentication';
import { ResetPassword as ResetPasswordContract } from '../../../../../shared/contracts/authentication';
import { Form } from '../../../components/Form';
import { InputRenderer } from '../../../components/FormInputs/Renderer';
import { Logo } from '../../../components/UnauthenticatedLogo';
Expand Down Expand Up @@ -73,7 +73,7 @@ const ResetPassword = () => {

const [resetPassword, { error }] = useResetPasswordMutation();

const handleSubmit = async (body: ResetPassword.Request['body']) => {
const handleSubmit = async (body: ResetPasswordContract.Request['body']) => {
const res = await resetPassword(body);

if ('data' in res) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { useTypedSelector } from '../../../../core/store/hooks';
import { useNotification } from '../../../../features/Notifications';
import { useTracking } from '../../../../features/Tracking';
import { useAPIErrorHandler } from '../../../../hooks/useAPIErrorHandler';
import { useOnce } from '../../../../hooks/useOnce';
import { useRBAC } from '../../../../hooks/useRBAC';
import { useDeleteAPITokenMutation, useGetAPITokensQuery } from '../../../../services/apiTokens';
import { API_TOKEN_TYPE } from '../../components/Tokens/constants';
Expand Down Expand Up @@ -83,11 +82,11 @@ export const ListView = () => {
label: formatMessage(header.label),
}));

useOnce(() => {
React.useEffect(() => {
trackUsage('willAccessTokenList', {
tokenType: API_TOKEN_TYPE,
});
});
}, [trackUsage]);

const { data: apiTokens = [], isLoading, error } = useGetAPITokensQuery();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { useTypedSelector } from '../../../../core/store/hooks';
import { useNotification } from '../../../../features/Notifications';
import { useTracking } from '../../../../features/Tracking';
import { useAPIErrorHandler } from '../../../../hooks/useAPIErrorHandler';
import { useOnce } from '../../../../hooks/useOnce';
import { useRBAC } from '../../../../hooks/useRBAC';
import {
useDeleteTransferTokenMutation,
Expand Down Expand Up @@ -80,11 +79,11 @@ const ListView = () => {
navigate({ search: qs.stringify({ sort: 'name:ASC' }, { encode: false }) });
}, [navigate]);

useOnce(() => {
React.useEffect(() => {
trackUsage('willAccessTokenList', {
tokenType: TRANSFER_TOKEN_TYPE,
});
});
}, [trackUsage]);

const headers = tableHeaders.map((header) => ({
...header,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/admin/admin/tests/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ export interface RenderOptions {
* for use of testing components within the Strapi Admin.
*/
const render = (
ui: React.ReactElement,
ui: React.ReactElement<any>,
{ renderOptions, userEventOptions, initialEntries, providerOptions }: RenderOptions = {}
): RenderResult & { user: ReturnType<typeof userEvent.setup> } => {
const { wrapper: Wrapper = fallbackWrapper, ...restOptions } = renderOptions ?? {};
Expand Down
4 changes: 2 additions & 2 deletions packages/core/admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@
"@types/sanitize-html": "2.11.0",
"@vitejs/plugin-react-swc": "3.6.0",
"koa-body": "6.0.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react": "rc",
"react-dom": "rc",
"react-router-dom": "6.22.3",
"styled-components": "6.1.8",
"vite": "5.1.6",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,13 +337,15 @@ const Field = ({ attribute, components, name, index, onMoveField, onRemoveField
dragPreviewRef(getEmptyImage(), { captureDraggingState: false });
}, [dragPreviewRef]);

// @ts-expect-error – issue with react-dnd with react19 types
const composedRefs = useComposedRefs<HTMLSpanElement>(dragRef, objectRef);

const handleRemoveField: React.MouseEventHandler<HTMLButtonElement> = (e) => {
e.stopPropagation();
onRemoveField(e);
};

// @ts-expect-error – issue with react-dnd with react19 types
const tempRefs = useComposedRefs<HTMLSpanElement>(dropRef, objectRef);

if (!value) {
Expand All @@ -361,6 +363,7 @@ const Field = ({ attribute, components, name, index, onMoveField, onRemoveField
background="neutral100"
hasRadius
style={{ opacity: isDragging ? 0.5 : 1 }}
// @ts-expect-error – issue with react-dnd with react19 types
ref={dropRef}
gap={3}
cursor="pointer"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {

import type { Schema } from '@strapi/types';

const iconByTypes: Record<Schema.Attribute.Kind, React.ReactElement> = {
const iconByTypes: Record<Schema.Attribute.Kind, React.ReactElement<any>> = {
biginteger: <NumberField />,
boolean: <BooleanField />,
date: <DateField />,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const LocationDisplay = () => {
return <span data-testid="location">{location.search}</span>;
};

const render = (ui: React.ReactElement) =>
const render = (ui: React.ReactElement<any>) =>
renderRTL(ui, {
renderOptions: {
wrapper({ children }) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ type UseDragAndDropReturn<E extends Element = HTMLElement> = [
isOverDropTarget: boolean;
direction: (typeof DIRECTIONS)[keyof typeof DIRECTIONS] | null;
},
objectRef: React.RefObject<E>,
objectRef: React.RefObject<E | null>,
dropRef: ConnectDropTarget,
dragRef: ConnectDragSource,
dragPreviewRef: ConnectDragPreview,
Expand Down
6 changes: 0 additions & 6 deletions packages/core/content-manager/admin/src/hooks/useOnce.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/core/content-manager/admin/src/hooks/usePrev.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useEffect, useRef } from 'react';

export const usePrev = <T>(value: T): T | undefined => {
const ref = useRef<T>();
const ref = useRef<T>(undefined);

useEffect(() => {
ref.current = value;
Expand Down
Loading
Loading