如何在带有Typescript的React中使用refs

我在React中使用Typescript。我在理解如何使用refs方面遇到麻烦,以便相对于refs引用的react节点获得静态类型和智能感知。我的代码如下。

import * as React from 'react';

interface AppState {
    count: number;
}

interface AppProps {
    steps: number;
}

interface AppRefs {
    stepInput: HTMLInputElement;
}

export default class TestApp extends React.Component<AppProps, AppState> {

constructor(props: AppProps) {
    super(props);
    this.state = {
        count: 0
    };
}

incrementCounter() {
    this.setState({count: this.state.count + 1});
}

render() {
    return (
        <div>
            <h1>Hello World</h1>
            <input type="text" ref="stepInput" />
            <button onClick={() => this.incrementCounter()}>Increment</button>
            Count : {this.state.count}
        </div>
    );
}}
JinJinLEY2020/03/12 15:07:51
class SelfFocusingInput extends React.Component<{ value: string, onChange: (value: string) => any }, {}>{
    ctrls: {
        input?: HTMLInputElement;
    } = {};
    render() {
        return (
            <input
                ref={(input) => this.ctrls.input = input}
                value={this.props.value}
                onChange={(e) => { this.props.onChange(this.ctrls.input.value) } }
                />
        );
    }
    componentDidMount() {
        this.ctrls.input.focus();
    }
}

把它们放在一个物体上

十三小哥2020/03/12 15:07:51

对于 TypeScript用户,不需要构造函数。

...

private divRef: HTMLDivElement | null = null

getDivRef = (ref: HTMLDivElement | null): void => {
    this.divRef = ref
}

render() {
    return <div ref={this.getDivRef} />
}

...

Gil村村2020/03/12 15:07:51

只是添加了一种不同的方法-您可以简单地投射引用,例如:

let myInputElement: Element = this.refs["myInput"] as Element
乐米亚2020/03/12 15:07:51

我总是这样做,在这种情况下要获取参考

let input: HTMLInputElement = ReactDOM.findDOMNode<HTMLInputElement>(this.refs.input);

猪猪十三2020/03/12 15:07:51

缺少完整的示例,这是我的小测试脚本,用于在使用React和TypeScript时获取用户输入。部分基于其他评论以及此链接https://medium.com/@basarat/strongly-typed-refs-for-react-typescript-9a07419f807#.cdrghertm

/// <reference path="typings/react/react-global.d.ts" />

// Init our code using jquery on document ready
$(function () {
    ReactDOM.render(<ServerTime />, document.getElementById("reactTest"));
});

interface IServerTimeProps {
}

interface IServerTimeState {
    time: string;
}

interface IServerTimeInputs {
    userFormat?: HTMLInputElement;
}

class ServerTime extends React.Component<IServerTimeProps, IServerTimeState> {
    inputs: IServerTimeInputs = {};

    constructor() {
        super();
        this.state = { time: "unknown" }
    }

    render() {
        return (
            <div>
                <div>Server time: { this.state.time }</div>
                <input type="text" ref={ a => this.inputs.userFormat = a } defaultValue="s" ></input>
                <button onClick={ this._buttonClick.bind(this) }>GetTime</button>
            </div>
        );
    }

    // Update state with value from server
    _buttonClick(): void {
    alert(`Format:${this.inputs.userFormat.value}`);

        // This part requires a listening web server to work, but alert shows the user input
    jQuery.ajax({
        method: "POST",
        data: { format: this.inputs.userFormat.value },
        url: "/Home/ServerTime",
        success: (result) => {
            this.setState({ time : result });
        }
    });
}

}

ASamGreen2020/03/12 15:07:51

一种方法(我一直在做)是手动设置:

refs: {
    [string: string]: any;
    stepInput:any;
}

那么您甚至可以将其包装在一个更好的getter函数中(例如here):

stepInput = (): HTMLInputElement => ReactDOM.findDOMNode(this.refs.stepInput);
MandyL2020/03/12 15:07:51

编辑:这已不再是使用Typescript引用的正确方法。查看Jeff Bowen的答案,并对其进行投票以提高其可见度。

找到了问题的答案。在类中使用下面的引用。

refs: {
    [key: string]: (Element);
    stepInput: (HTMLInputElement);
}

感谢@basarat指出正确的方向。