使用typescript开发的react组件时遇到的类型问题(ref)

package.json引入的依赖
image.png
node_modules中组件d.ts文件声明
image.png

import React, {Component} from 'react';
import isEqual from 'lodash/isEqual';
import cloneDeep from 'lodash/cloneDeep';
import JSONEditor from 'jsoneditor';
import 'jsoneditor/dist/jsoneditor.css';
import './JsonEditor.css';

interface IProps {
    schema: {}
    json: {}
    text: string
    mode: string,
    indentation?: any,
    onChangeText(text: string): any,
    onModeChange(mode: string): any
}

interface IState {
}

class JsonEditor extends React.PureComponent<IProps, IState> {
    private readonly wrapper: HTMLElement;
    private jsonEditor: any;
    private schema: any;
    
    constructor(props: IProps) {
        super(props);
        this.wrapper = React.createRef();
    }
    componentDidMount () {
        // copy all properties into options for the editor
        // (except the properties for the JSONEditorReact component itself)
        let options = Object.assign({}, this.props);
        // delete options.json;
        // delete options.text;

        // @ts-ignore
        this.jsonEditor = new JSONEditor(this.wrapper, options);

        if ('json' in this.props) {
            this.jsonEditor.set(this.props.json);
        }
        if ('text' in this.props) {
            this.jsonEditor.setText(this.props.text);
        }

        this.schema = cloneDeep(this.props.schema);
        // this.schemaRefs = cloneDeep(this.props.schemaRefs);
    }

    componentDidUpdate() {
        if ('json' in this.props) {
            this.jsonEditor.update(this.props.json);
        }

        if ('text' in this.props) {
            this.jsonEditor.updateText(this.props.text);
        }

        if ('mode' in this.props) {
            this.jsonEditor.setMode(this.props.mode);
        }

        // store a clone of the schema to keep track on when it actually changes.
        // (When using a PureComponent all of this would be redundant)
        const schemaChanged = !isEqual(this.props.schema, this.schema);
        // const schemaRefsChanged = !isEqual(this.props.schemaRefs, this.schemaRefs);
        if (schemaChanged) {
            this.schema = cloneDeep(this.props.schema);
            // this.schemaRefs = cloneDeep(this.props.schemaRefs);
            this.jsonEditor.setSchema(this.props.schema);
        }
    }

    componentWillUnmount () {
        if (this.jsonEditor) {
            this.jsonEditor.destroy();
        }
    }

    render() {
        return (
            <div className="jsoneditor-react-container" ref={this.wrapper} />
        );
    }
}

export default JsonEditor

个人理解是使用的时候, 创建JSONEditor的对象, 需要传入一个dom元素和一个option对象, 这里dom元素使用React.createRef来获取..但是这个类型总是匹配不上,JSONEditor要求的是传入一个HTMLElement类型,但是div元素的ref属性对应的应该是HTMLDivElement类型,React.createRef对应的是React.RefObject<T>类型

private readonly wrapper: HTMLElement;
this.wrapper = React.createRef();
ref={this.wrapper}

所有上述几个地方对应的类型应该如何统一

因为不是专业前端, 还请专业人士帮个忙解惑, 谢谢
最终目的, 需要一个react的json编辑器组件, 且是使用typescipt..

相关资料:
jsoneditor项目github地址
jsoneditor官方示例代码(jsx)
基于jsoneditor二次封装的json编辑器组件(react版jsx)

阅读 5.5k
4 个回答
private readonly wrapper: React.RefObject<HTMLDivElement>;

this.jsonEditor = new JSONEditor(this.wrapper.current, options);

类型上大概这样. dom 是挂在 ref 一个 current 属性上的

严格点还要加上 null 判断

可以创建的是时候指定泛型类型:

React.createRef<HTMLDivElement>();

问题解决了..
ref如果用的是这种回调函数
ref={elem => this.wrapper = elem}
this.wrapper直接代表dom节点
ref如果用下面这种方式
ref={this.wrapper}
this.wrapper = React.createRef();
this.wrapper.current代表dom元素..
说的可能不太专业, 反正上面的代码this.wrapper替换成this.wrapper.current就可以了

新手上路,请多包涵

如果提示null的话可以用!断言一下

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题