Open bokibo opened 2 years ago
I'm also encountering this. It seems to work fine with React 18, so here's my current workaroud:
import Modal from 'react-modal';
import { ComponentType } from 'react';
…
const ModalSafeForReact18 = Modal as ComponentType<ReactModal['props']>;
return <ModalSafeForReact18>…</ModalSafeForReact18>;
@btraut @bokibo Can you provide the actual error that this version is throwing, please?
Its instance type 'Modal' is not a valid JSX element.
The types returned by 'render()' are incompatible between these types.
Type 'import("<my app's path>/node_modules/@types/react-dom/node_modules/@types/react/index").ReactNode' is not assignable to type 'React.ReactNode'.
Type '{}' is not assignable to type 'ReactNode'.
88 <Modal
~~~~~~~~~~
From what I can tell from my yarn.lock
, it looks like "@types/react": "*"
is resolving to version 17.0.34
and my app ("@types/react": "^18.0.20"
) is resolving to 18.0.20
. Those are likely incompatible.
This is a typescript thing...it's very sad. I don't know how the react version is injected on the react-modal type definition, so I can't help.
If you want to give it a try here is type definitions DefinitelyTyped/react-modal. It must be easy, but I don't have much time to work on this.
I'm flaging as 'not a bug', because it isn't really a bug, but a type definition problem that affects only typescript projects.
Or...you can open a bug on the type repository and mention me, so I can follow up.
I'm using react-modal 3.15.1
with @types/react-modal 3.13.1
, react 18.2.0
and typescript 4.8.4
without any error like that. Could you please provide some actual code or a codepen/playground that gives this error, @bokibo?
I'm having the same problem :/
I have the solution.
I realized that some of the packages were still using @types/react@17.0.44
, including the react-modal
one:
yarn list --pattern "@types/react"
├─ @types/react-dom@18.0.7
│ └─ @types/react@17.0.44
├─ @types/react-modal@3.13.1
│ └─ @types/react@17.0.44
├─ @types/react@18.0.22
This was caused by two things:
@types/react-modal
has this in its package.json
: "dependencies": {
"@types/react": "*"
},
"resolutions": {
"@types/react": "17.0.44"
}
Solution:
resolutions
part of my package.json
file.rm -rf node_modules && rm yarn.lock && yarn install
Hope this helps ! 😗
@NathanVss That's awesome.
As this is related to types, this package is not the one to blame.
This problem needs to be opened on https://github.com/DefinitelyTyped/DefinitelyTyped.
Hi everyone. Thanks for the answers. I haven't had time to respond so I did a rollback to react 17. Today I had some free time I tried again and I get the same error. I agree it is a typescript thing but could someone help me solve it?
This is the component that uses Reactmodal. I did a thing with ModalSafeForReact18 that @btraut mentioned.
import React, {useEffect, useLayoutEffect, useState} from "react";
import ReactModal from "react-modal";
import {IAlertModalProps} from "./alertModal.props";
import {Overlay} from "../modal/Modal.style";
import AlertModalContainer from "./alert-modal-container/AlertModalContainer";
import Modal from 'react-modal';
import { ComponentType } from 'react';
ReactModal.setAppElement('#root');
const ModalSafeForReact18 = Modal as ComponentType<ReactModal['props']>;
const AlertModal: React.FC<React.PropsWithChildren<IAlertModalProps>> =
({isOpen, type, afterOpen, afterClose, closeModal, children}) => {
return <ModalSafeForReact18
isOpen={isOpen}
onAfterOpen={onOpen}
onAfterClose={onClose}
contentElement={(props) =>
<AlertModalContainer
type={type}
onClose={closeModal}
{...props}>
{children}
</AlertModalContainer>}
overlayElement={(props, contentElement) =>
<Overlay {...props}>{contentElement}</Overlay>}
overlayClassName={'overlay'}
/>
}
export default AlertModal
And the AlertModalContainer component
import React from "react";
import {Wrapper, CloseButton, Title, Icon} from "./AlertModalContainer.style";
import {AlertModalType} from "../alertModal.props";
interface IAlertModalContainerProps {
type: AlertModalType,
onClose: () => void
}
const AlertModalContainer: React.FC<IAlertModalContainerProps> =
React.forwardRef<HTMLDivElement, IAlertModalContainerProps>(({type, onClose, children}) => {
return <Wrapper>
<Icon type={type}>{type === 'success' ?
<i className={'ico-Check'}/> : type === 'error' ?
<i className={'ico-Exit-outlined'}/> :
<i className={'ico-Information-outlined'}/>}</Icon>
<Title type={type}>{type === 'success' ? 'Success!' : type === 'error' ? 'Failure!' : 'Almost Done!'}</Title>
{children}
<CloseButton onClick={() => onClose()}>{type === 'success' ? 'Done' : 'Close'}</CloseButton>
</Wrapper>
})
export default AlertModalContainer
And these are two errors I get.
on AlertModalContainer inside AlertModal component
on children in AlertModalContainer component
When I add children type to IAlertModalContainerProps as ReactNode then on the "overlayElement" I get
And when I change children to ReactElement then I get this error on children on AlertModalContainter
Could someone please help?
Excuse my poor English.
Component in React 18 can no longer pass children implicitly. To do this, we need to add a children field of type React.ReactNode to Props.
Therefore, to extend the react-modal's Modal type in the project, the following type definition was written. This allows the Modal Component to specify a child component. What do you think?
(react-modal.d.ts)
import React from 'react'
import { OriginalProps } from 'react-modal'
declare module 'react-modal' {
interface Props extends OriginalProps {
children?: React.ReactNode
}
}
@kento-hamaguchi-md Interesting...is this type definition also valid for React <18?
@diasbruno Yes. My project is React 18. I am able to build and run it without any problems. However, this is not an essential solution, but an interim method.
I am sorry if this is not the cause of the issue in this Issue.
Sorry, the check on the VSCode editor seemed to resolve the problem, but in the actual build process, the problem continued. I will look into it again to see if the type definition is not passing or if there are other underlying issues.
@kento-hamaguchi-md That's unfortunate, but great idea.This actually lines up with @bokibo's comment.
You can find more information on https://github.com/DefinitelyTyped/DefinitelyTyped for the react-modal's type definition.
Keep me posted with your findings and I'll be happy to help.
I have tried many things, but adding this setting to tsconfig.json
will make the type definitions strict at build time.
The type definition file that overrides the react-modal definition should be placed in src/types/global/react-modal.d.ts
. It seems to be the specification that it should not be placed directly in types, but through, for example, global.
{
"compilerOptions": {
"typeRoots": ["src/types"],
However, after doing this and reviewing the Next.js Lint settings, etc., the build now passes even if the typeRoots setting is turned off. I am sorry, but I could not find out exactly what caused the problem.
However, as for the type definition issue, the aforementioned react-modal.d.ts
seems to work fine. I guess it depends on the environment of each project. Sorry for the reference, but the above is the result of our investigation.
Bom trabalho! This one is actually annoying as hell.
Here is a checklist:
Things that resolved it for me with React 18:
react-modal
(3.16.1)@types/react-modal
(3.13.1)@chinanderm thank you, man. I tried before only to update to the latest version, but removing and installing all deps helped me.
@denibudeyko Would you like add this note on the readme? Well, it seems the way to go...
I had luck updating my .tsconfig.json in my project to the following:
{
"compilerOptions": {
"target": "es2020",
"lib": [
"dom",
"dom.iterable"
],
"paths": {
"react": [ "./node_modules/@types/react" ],
"dompurify": [ "./node_modules/@types/dompurify" ]
},
"strict": true,
"jsx": "react",
},
"include": [
"src/**/*"
, "tests" ]
}
I previously had compilerOptions.jsx
set to react-jsx
; simply renaming it to react
seemed to resolve the problem. Also being sure to import the relevant items under paths
.
After that, I was able to build:
115 B build/1abe08b3249335736c0f016631f03702.js
115 B build/1d48b3a38a76bfc80d5718a91fd4c252.js
115 B build/23e579d49d8f8206607964d627b336b7.js
115 B build/49db9cf6f30a219cf140f7846d87a418.js
115 B build/a1883a50fa7e229ceeb72b409367a1b1.js
115 B build/b3c8fac34d63a9fe758b737a2560c911.js
115 B build/bf24eb9b91f882cafcfa6a7e8e3c56b1.js
114 B build/1046b30afca9b1942dd448bcafff2a95.js
114 B build/eab387dee57def86c245a3d71365a614.js
114 B build/f574c6ed6a178b4374b7c570ab2fce5f.js
113 B build/c98e74fc97b04fe8bf43dcdff549afcf.js
112 B build/0ffb18fb70c87335edee31a479f58a43.js
The bundle size is significantly larger than recommended.
Consider reducing it with code splitting: https://goo.gl/9VhYWB
You can also analyze the project dependencies: https://goo.gl/LeUzfb
The project was built assuming it is hosted at /.
You can control this with the homepage field in your package.json.
The build folder is ready to be deployed.
You may serve it with a static server:
npm install -g serve
serve -s build
Find out more about deployment here:
https://cra.link/deployment
My package.json:
"dependencies": {
"@auth0/auth0-react": "^2.1.1",
"@ctrl/tinycolor": "^3.6.0",
"@emotion/react": "^11.7.1",
"@emotion/styled": "^11.6.0",
"@hookform/resolvers": "^3.1.0",
"@material-ui/utils": "^4.11.3",
"@mui/icons-material": "^5.13.7",
"@mui/material": "^5.0.6",
"@mui/styles": "^5.13.7",
"@mui/utils": "^5.13.1",
"@mui/x-data-grid": "^5.6.0",
"@testing-library/jest-dom": "^5.14.1",
"@types/dompurify": "^3.0.2",
"@types/node": "^16.11.25",
"@types/react-dom": "^17.0.10",
"@types/react-modal": "^3.13.1",
"ace-builds": "^1.4.14",
"dompurify": "^3.0.4",
"history": "^5.3.0",
"jss": "^10.10.0",
"jss-preset-default": "^10.10.0",
"moment": "^2.29.4",
"mui-color-input": "^1.1.0",
"react": "^18.2.0",
"react-ace": "^9.5.0",
"react-dom": "*",
"react-hook-form": "^7.45.1",
"react-modal": "^3.14.4",
"react-quill": "^2.0.0",
"react-router-dom": "^6.14.1",
"react-scripts": "5.0.0",
"style-loader": "^3.3.2",
"typescript": "^4.4.4",
"uuid": "^9.0.0",
"uuidv4": "^6.2.13",
"web-vitals": "^2.1.4",
"yup": "^1.2.0"
},
Hi,
I am using this component for certain and it works perfect, don't have any problems. But yesterday I tried to update react from v17 to v18 and after update I got this error
'ReactModal' cannot be used as a JSX component.
Is there any way to fix it so I could continue using this component or this is caused by new react version and fix is needed? So far I did revert to react v17 and it works but in the future I would like to update to version 18.
Thank you