使用 Typescript 和 JSX 响应事件处理程序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31970720/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 03:03:55  来源:igfitidea点击:

React event handlers with Typescript and JSX

typescriptreactjsreact-jsx

提问by Ian G

I'm having problems updating state in a React component I'm writing in TypeScript (React with Addons 0.13.3, Typescript 1.6.0-dev.20150804, definition file from http://definitelytyped.org/).

我在用 TypeScript 编写的 React 组件中更新状态时遇到问题(React with Addons 0.13.3,Typescript 1.6.0-dev.20150804,来自http://definelytyped.org/ 的定义文件)。

/// <reference path="react/react-addons.d.ts" />
import React = require("react/addons");

interface AppState {
}

interface TestState {
    liked: boolean,
    name: string
}

class Tester extends React.Component<any, TestState> {
    constructor(props) {
        super(props);
        this.state = { liked: false, name: "Anders" };
    }

    handleClick(evt, domNode): void {
        this.setState({ liked: !this.state.liked, name: this.state.name });
    }

    handleChange(evt, a, b, c): void {
        this.setState({ liked: this.state.liked, name: evt.target.value });
    }

    render() {
        var text = this.state.liked ? "liked " : "haven't liked "
        return (<div>You {text} {this.state.name} 
            <button onClick={this.handleClick}>Like</button>
            <input value={this.state.name} onChange={this.handleChange} />
        </div>);
    }
}

class App extends React.Component<{}, AppState> {
    constructor(props) {
        super(props);
    }

    render() {
        return (<div>
            <Tester />
        </div>);
    }
}

function Factory(props: {}) {
  return React.createElement(App, props);
}

export = Factory;

The calling code is

调用代码是

/// <reference path="react/react-addons.d.ts" />
import React = require("react/addons");
import App = require("app");

React.render(App({}), document.getElementById("jsapp"));

The component renders as I would expect but handleClickand handleChangemethods don't update the state correctly. If I put breakpoints in those two methods and renderthen I see the following values for this:

该组件呈现为我所期望的,但handleClickhandleChange方法不正确地更新状态。如果我在这两种方法中放置断点,render然后我会看到以下值this

  • render: thisis a Tester object (what I would expect).
  • handleChange: thisis a ReactClass.createClass.Constructor.
  • handleClick: thisis a reference to the Windowobject.
  • render:this是一个 Tester 对象(我所期望的)。
  • handleChange:this是一个ReactClass.createClass.Constructor
  • handleClick:this是对Window对象的引用。

The latter two mean that the state object isn't available.

后两个意味着状态对象不可用。

Any suggestions gratefully received.

感谢您收到任何建议。

采纳答案by Buzinas

You must change your render method:

您必须更改渲染方法:

render() {
    // ...
        <button onClick={this.handleClick.bind(this)}>Like</button>
        <input value={this.state.name} onChange={this.handleChange.bind(this)} />
    // ...
}

Since you're calling an event, the thiskeyword will be changed to the event's default context. By using .bind(this)you ensure that the context being called will be the instance of your class.

由于您正在调用事件,因此this关键字将更改为事件的默认上下文。通过使用,.bind(this)您可以确保被调用的上下文将是您的类的实例。

回答by shadeglare

You have to bind methods with thisbecause you don't use React.createClassthat does it automatically. Example with a class syntax:

您必须绑定方法,this因为您React.createClass不会自动使用它。类语法示例:

class Counter extends React.Component {
  constructor() {
    super();
    this.handleChange = this.handleChange.bind(this);
    this.handleClick = this.handleClick.bind(this);
  }
  handleChange() {
    ...
  }
  handleClick() {
    ...
  }
}

回答by Sam Sippe

Another method is to use fat arrow functions for event handlers which get automatic "this" binding.

另一种方法是对获得自动“this”绑定的事件处理程序使用粗箭头函数。

 handleClick = (evt, domNode):void => {
     this.setState({ liked: !this.state.liked, name: this.state.name });
 };

 <button onClick={() => this.handleClick()}>Like</button>