sekoyo / react-image-crop

A responsive image cropping tool for React
ISC License
3.79k stars 339 forks source link

'ReactCrop' cannot be used as a JSX component. #481

Open etomarat opened 2 years ago

etomarat commented 2 years ago

Hi! I have a typescript error. What im doing wrong?

image

Full error text:

'ReactCrop' cannot be used as a JSX component.
  Its instance type 'ReactCrop' is not a valid JSX element.
    Types of property 'refs' are incompatible.
      Type '{ [key: string]: import("/Users/etomarat/Projects/niti/server/node_modules/@types/react/index").ReactInstance; }' is not assignable to type '{ [key: string]: React.ReactInstance; }'.
        'string' index signatures are incompatible.
          Type 'import("/Users/etomarat/Projects/niti/server/node_modules/@types/react/index").ReactInstance' is not assignable to type 'React.ReactInstance'.
            Type 'Component<any, {}, any>' is not assignable to type 'ReactInstance'.
              Type 'import("/Users/etomarat/Projects/niti/server/node_modules/@types/react/index").Component<any, {}, any>' is not assignable to type 'React.Component<any, {}, any>'.
                The types returned by 'render()' are incompatible between these types.
                  Type 'import("/Users/etomarat/Projects/niti/server/node_modules/@types/react/index").ReactNode' is not assignable to type 'React.ReactNode'.
                    Type '{}' is not assignable to type 'ReactNode'.

My code:

import React, { FC, useState, useRef } from 'react'
import { DropZone, FormGroup, Label, Box, Icon, Input, Button } from '@adminjs/design-system'
import styled from 'styled-components';
import ReactCrop, { centerCrop, makeAspectCrop, Crop, PixelCrop } from 'react-image-crop'
// import 'react-image-crop/src/ReactCrop.scss'

import ImageEditorControls from './imageEditorControls'

const ImageEditor: FC = () => {
  const [imgSrc, setImgSrc] = useState('/static/kotestdinyu.png')
  const previewCanvasRef = useRef<HTMLCanvasElement>(null)
  const imgRef = useRef<HTMLImageElement>(null)
  const [crop, setCrop] = useState<Crop>()
  const [completedCrop, setCompletedCrop] = useState<PixelCrop>()
  const [scale, setScale] = useState(1)
  const [rotate, setRotate] = useState(0)
  const [aspect, setAspect] = useState<number | undefined>(9 / 16)

  return (
    <>
      <Box flex height='100%'>
        <Left bg='bg'>
          <CropHolder>
            <ReactCrop
              crop={crop}
              onChange={(_, percentCrop) => setCrop(percentCrop)}
              onComplete={(c) => setCompletedCrop(c)}
              aspect={aspect}
            >
              <Image
                wOffset
                ref={imgRef}
                alt="Crop me"
                src={imgSrc}
                style={{ transform: `scale(${scale}) rotate(${rotate}deg)` }}
                // onLoad={onImageLoad}
              />
            </ReactCrop>
          </CropHolder>
          <ImageEditorControls />
        </Left>
        <Right>
          <Image src="/static/kotestdinyu.png"/>
        </Right>
      </Box>
    </>
  );
};

Thanks for considering my request!

andreiaf commented 2 years ago

This is most likely due to the new react 18 types. I had this on other projects. I fixed it in my projects by adding this to my package.json

  "resolutions": {
    "@types/react": "^17.0.44",
    "@types/react-dom": "^17.0.16"
}

https://github.com/DefinitelyTyped/DefinitelyTyped/pull/56210

etomarat commented 2 years ago

Hi @andreiaf ! I am using react ^16

andreiaf commented 2 years ago

I still suggest that you check the current version of your @types/react They might've been updated to the latest 18 by some other dependency even if your react itself is still 16 You can do yarn why @types/react or npm list @types/react

etomarat commented 2 years ago

@andreiaf thanks for you suggest! But i have "@types/react": "^16". This is my dependencies section:

"dependencies": {
    "@adminjs/design-system": "^2.2.4",
    "@adminjs/express": "^4.1.0",
    "@adminjs/mongoose": "^2.0.2",
    "@adminjs/upload": "^2.0.2",
    "adminjs": "^5.10.0",
    "connect-mongo": "^4.6.0",
    "crypto-js": "^4.1.1",
    "dotenv": "^16.0.0",
    "express": "^4.18.0",
    "express-formidable": "^1.2.0",
    "express-session": "^1.17.2",
    "mongoose": "^6.3.1",
    "patch-package": "^6.4.7",
    "postinstall-postinstall": "^2.1.0",
    "react-cropper": "^2.1.8",
    "react-image-crop": "^10.0.0",
    "styled-components": "^5.3.5",
    "styled-system": "^5.1.5"
  },
  "devDependencies": {
    "@types/crypto-js": "^4.1.1",
    "@types/express": "^4.17.13",
    "@types/express-session": "^1.17.4",
    "@types/node": "^17.0.29",
    "@types/react": "^16",
    "@types/styled-components": "^5.1.25",
    "@typescript-eslint/eslint-plugin": "^5.21.0",
    "@typescript-eslint/parser": "^5.21.0",
    "concurrently": "^7.1.0",
    "eslint": "^8.14.0",
    "nodemon": "^2.0.15",
    "tslint": "^6.1.3",
    "typescript": "^4.6.3"
  }

React is a peer dependency of one of the packages I use. In node_modules/react/package.json version is "version": "16.14.0"

sekoyo commented 2 years ago

@andreiaf thanks for you suggest! But i have "@types/react": "^16". This is my dependencies section:

"dependencies": {
    "@adminjs/design-system": "^2.2.4",
    "@adminjs/express": "^4.1.0",
    "@adminjs/mongoose": "^2.0.2",
    "@adminjs/upload": "^2.0.2",
    "adminjs": "^5.10.0",
    "connect-mongo": "^4.6.0",
    "crypto-js": "^4.1.1",
    "dotenv": "^16.0.0",
    "express": "^4.18.0",
    "express-formidable": "^1.2.0",
    "express-session": "^1.17.2",
    "mongoose": "^6.3.1",
    "patch-package": "^6.4.7",
    "postinstall-postinstall": "^2.1.0",
    "react-cropper": "^2.1.8",
    "react-image-crop": "^10.0.0",
    "styled-components": "^5.3.5",
    "styled-system": "^5.1.5"
  },
  "devDependencies": {
    "@types/crypto-js": "^4.1.1",
    "@types/express": "^4.17.13",
    "@types/express-session": "^1.17.4",
    "@types/node": "^17.0.29",
    "@types/react": "^16",
    "@types/styled-components": "^5.1.25",
    "@typescript-eslint/eslint-plugin": "^5.21.0",
    "@typescript-eslint/parser": "^5.21.0",
    "concurrently": "^7.1.0",
    "eslint": "^8.14.0",
    "nodemon": "^2.0.15",
    "tslint": "^6.1.3",
    "typescript": "^4.6.3"
  }

React is a peer dependency of one of the packages I use. In node_modules/react/package.json version is "version": "16.14.0"

I don't see react listed as a dep there?

etomarat commented 2 years ago

@DominicTobias yes, React is a peer dependency of one of the packages I use. In node_modules/react/package.json version is "version": "16.14.0"

sekoyo commented 2 years ago

I see, if you use React directly it should always be a depedency you declare, peer dependencies don't get automatically installed so I guess something else has installed it, but your app should be the one that lists what version of React it wants if it uses it. Also is there a reason you don't upgrade to 17 or 18? Usually a package can work on those too. Although not sure what the issue is in your case/v16, a bit hard to debug without a reproduction

etomarat commented 2 years ago

Thanks for your advice! I added react@^16 to my project, but unfortunately it didn't solve the problem. I can't switch to React above version 16, because one of the main packages in my application only supports version 16. If I install a new version, then there are problems with types already in this "main" package.