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

'ReactModal' cannot be used as a JSX component. #960

Open
bokibo opened this issue Aug 16, 2022 · 23 comments
Open

'ReactModal' cannot be used as a JSX component. #960

bokibo opened this issue Aug 16, 2022 · 23 comments

Comments

@bokibo
Copy link

bokibo commented Aug 16, 2022

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

@btraut
Copy link

btraut commented Sep 21, 2022

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>;

@diasbruno
Copy link
Collaborator

@btraut @bokibo Can you provide the actual error that this version is throwing, please?

@btraut
Copy link

btraut commented Sep 21, 2022

  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.

@diasbruno
Copy link
Collaborator

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.

@diasbruno
Copy link
Collaborator

I'm flaging as 'not a bug', because it isn't really a bug, but a type definition problem that affects only typescript projects.

@diasbruno
Copy link
Collaborator

Or...you can open a bug on the type repository and mention me, so I can follow up.

@memark
Copy link
Contributor

memark commented Oct 12, 2022

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?

@NathanVss
Copy link

I'm having the same problem :/

@NathanVss
Copy link

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": "*"
    },
  • I had this in my package.json
  "resolutions": {
    "@types/react": "17.0.44"
  }

Solution:

  • I removed the resolutions part of my package.json file.
  • Run rm -rf node_modules && rm yarn.lock && yarn install

Hope this helps ! 😗

@diasbruno
Copy link
Collaborator

diasbruno commented Oct 25, 2022

@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.

@bokibo
Copy link
Author

bokibo commented Dec 17, 2022

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

  • TS2322: Type '{ children: ReactNode; key?: Key | null | undefined; slot?: string | undefined; style?: CSSProperties | undefined; title?: string | undefined; defaultChecked?: boolean | undefined; ... 254 more ...; onClose: () => void; }' is not assignable to type 'IntrinsicAttributes & IAlertModalContainerProps'.   Property 'children' does not exist on type 'IntrinsicAttributes & IAlertModalContainerProps'.

on children in AlertModalContainer component

  • TS2339: Property 'children' does not exist on type 'IAlertModalContainerProps'.

When I add children type to IAlertModalContainerProps as ReactNode then on the "overlayElement" I get

  • Type 'ReactElement<any, string | JSXElementConstructor>' is not assignable to type 'ReactNode'.

And when I change children to ReactElement then I get this error on children on AlertModalContainter

  • TS2322: Type 'ReactNode' is not assignable to type 'ReactElement<any, string | JSXElementConstructor>'.   Type 'undefined' is not assignable to type 'ReactElement<any, string | JSXElementConstructor>'.

Could someone please help?

@kento-hamaguchi-md
Copy link

kento-hamaguchi-md commented Jan 31, 2023

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
    }
}

@diasbruno
Copy link
Collaborator

diasbruno commented Feb 1, 2023

@kento-hamaguchi-md Interesting...is this type definition also valid for React <18?

@kento-hamaguchi-md
Copy link

kento-hamaguchi-md commented Feb 1, 2023

@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.

@kento-hamaguchi-md
Copy link

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.

@diasbruno
Copy link
Collaborator

@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.

@diasbruno
Copy link
Collaborator

Keep me posted with your findings and I'll be happy to help.

@kento-hamaguchi-md
Copy link

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.

@diasbruno
Copy link
Collaborator

Bom trabalho! This one is actually annoying as hell.

Here is a checklist:

  • Find which react and react-modal versions are incompatible
  • Understand the differences between type signature differences between react <18 and 18
  • Try to patch the definition and see if it's backwards compatible

@chinanderm
Copy link

Things that resolved it for me with React 18:

  • Latest version of react-modal (3.16.1)
  • Latest version of @types/react-modal (3.13.1)
  • Removed node_modules
  • Removed lock file
  • Reinstall all deps

@dcristafovici
Copy link

@chinanderm thank you, man. I tried before only to update to the latest version, but removing and installing all deps helped me.

@diasbruno
Copy link
Collaborator

@denibudeyko Would you like add this note on the readme? Well, it seems the way to go...

@Namone
Copy link

Namone commented Jul 7, 2023

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"
  },

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants