Refs is empty object {} when using correct reference pattern in React with TypeScript
问题:
我正在尝试从
我想知道的棘手的事情之一是TypeScript和React中的引用模式。但是,我在SO上发现了一个令人惊讶的问题,接下来我进行了设置。
预期:
ref模式将按预期工作,并且我可以访问底层函数(从对象)。
即我期望看到
实际:
尝试使用现在不建议使用的使用字符串的ref模式,这表明
码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | import * as React from"react"; import Cropper from 'react-cropper'; import 'cropperjs/dist/cropper.css'; export class ImageEditor extends React.Component { private cropRef : React.RefObject<Cropper>; constructor(props : any) { super(props); this.state = { src :"", cropResult :"" }; this.cropRef = React.createRef(); this.cropImage = this.cropImage.bind(this); this.onChange = this.onChange.bind(this); } onChange(e : any) { e.preventDefault(); let files; if (e.dataTransfer) { files = e.dataTransfer.files; } else if (e.target) { files = e.target.files; } const reader = new FileReader(); reader.onload = () => { this.setState({ src : reader.result }); }; reader.readAsDataURL(files[0]); } cropImage() { console.log(this.refs); if (typeof this.cropRef.current.getCroppedCanvas() === 'undefined') { return; } this.setState({ cropResult: this.cropRef.current.getCroppedCanvas().toDataURL(), }); } render() { return ( <input type="file" onChange={this.onChange} /> <br /> <br /> <Cropper style={{ height: 400, width: '100%' }} aspectRatio={16 / 9} preview=".img-preview" guides={false} src={this.state.src} ref={(cropper : any) => { this.cropRef = cropper}} /> Preview <span>Crop</span> <button onClick={this.cropImage} style={{ float: 'right' }}> Crop Image </button> <img style={{ width: '100%' }} src={this.state.cropResult} alt="cropped image" /> ); } } |
编辑:
为react-cropper编辑了index.d.ts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import * as cropperjs from 'cropperjs'; import * as React from 'react'; import Data = cropperjs.Data; import ContainerData = cropperjs.ContainerData; import ImageData = cropperjs.ImageData; import CanvasData = cropperjs.CanvasData; import CropBoxData = cropperjs.CropBoxData; import CroppedCanvasOptions = cropperjs.CroppedCanvasOptions; type ReactCropperProps = cropperjs.CropperOptions & React.AllHTMLAttributes<HTMLImageElement>; interface ReactCropper extends cropperjs {} // tslint:disable-line no-empty-interface declare class ReactCropper extends React.Component<ReactCropperProps> { on(eventname: string, callback: () => void): void; } export default ReactCropper; |
package.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | { "name":"name", "version":"1.0.0", "description":"packages for content", "main":"webpack.config.js", "scripts": { "build":"webpack", "test":"karma start karma.unit.build.js", "build-test":"karma start karma.unit.js", "coverage":"karma start karma.coverage.js" }, "author":"Joakim Bajoul Kakaei", "license":"ISC", "devDependencies": { "@types/chai":"^4.1.4", "@types/mocha":"^5.2.5", "@types/react":"^16.4.7", "@types/react-cropper":"./node_modules/react-cropper.fixed", "@types/react-dom":"^16.0.6", "@types/react-dropzone":"^4.2.0", "@types/sinon":"^5.0.1", "babel-core":"^6.26.3", "babel-loader":"^7.1.5", "chai":"^4.1.2", "css-loader":"^1.0.0", "istanbul-instrumenter-loader":"^3.0.1", "karma":"^2.0.5", "karma-chai":"^0.1.0", "karma-coverage":"^1.1.2", "karma-mocha":"^1.3.0", "karma-phantomjs-launcher":"^1.0.4", "karma-sinon":"^1.0.5", "karma-typescript-preprocessor2":"^1.2.1", "karma-webpack":"^3.0.0", "mocha":"^5.2.0", "mocha-webpack":"^1.1.0", "phantomjs-prebuilt":"^2.1.16", "sinon":"^6.1.4", "style-loader":"^0.21.0", "ts-loader":"^4.4.2", "ts-node":"^7.0.0", "typescript":"^2.9.2", "typings":"^2.1.1", "webpack":"^4.16.2", "webpack-cli":"^3.1.0" }, "dependencies": { "npm":"^6.3.0", "react":"^16.4.1", "react-cropper":"^1.0.1", "react-dom":"^16.4.1", "react-dropzone":"^4.2.13" } } |
node_modules / react-cropper / package.json:
1 2 3 4 5 | { "name":"@types/react-cropper", "dependencies": { } } |
看来您正在使用回调模式和
1 | ref={this.cropRef} |
如果要使用回调,则声明应为:
1 | private cropRef : Cropper; |
并且您将使用