使用 Typescript 和 JSX 响应事件处理程序
React event handlers with Typescript and JSX
我在用 TypeScript 编写的 React 组件中更新状态时遇到问题(React with Addons 0.13.3,Typescript 1.6.0-dev.20150804,来自 http://definitelytyped.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;
调用代码为
/// <reference path="react/react-addons.d.ts" />
import React = require("react/addons");
import App = require("app");
React.render(App({}), document.getElementById("jsapp"));
组件按我的预期呈现,但 handleClick
和 handleChange
方法未正确更新状态。如果我在这两个方法和 render
中放置断点,那么我会看到 this
:
的以下值
render
:this
是一个 Tester 对象(如我所料)。
handleChange
: this
是 ReactClass.createClass.Constructor
.
handleClick
: this
是对 Window
对象的引用。
后两者表示状态对象不可用。
非常感谢收到任何建议。
您必须使用 this
绑定方法,因为您不使用自动执行此操作的 React.createClass
。
使用 class 语法的示例:
class Counter extends React.Component {
constructor() {
super();
this.handleChange = this.handleChange.bind(this);
this.handleClick = this.handleClick.bind(this);
}
handleChange() {
...
}
handleClick() {
...
}
}
您必须更改渲染方法:
render() {
// ...
<button onClick={this.handleClick.bind(this)}>Like</button>
<input value={this.state.name} onChange={this.handleChange.bind(this)} />
// ...
}
由于您正在调用事件,因此 this
关键字将更改为事件的默认上下文。
通过使用 .bind(this)
,您确保被调用的上下文将是您的 class.
的实例
另一种方法是为事件处理程序使用粗箭头函数,它会自动 "this" 绑定。
handleClick = (evt, domNode):void => {
this.setState({ liked: !this.state.liked, name: this.state.name });
};
<button onClick={() => this.handleClick()}>Like</button>
我在用 TypeScript 编写的 React 组件中更新状态时遇到问题(React with Addons 0.13.3,Typescript 1.6.0-dev.20150804,来自 http://definitelytyped.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;
调用代码为
/// <reference path="react/react-addons.d.ts" />
import React = require("react/addons");
import App = require("app");
React.render(App({}), document.getElementById("jsapp"));
组件按我的预期呈现,但 handleClick
和 handleChange
方法未正确更新状态。如果我在这两个方法和 render
中放置断点,那么我会看到 this
:
render
:this
是一个 Tester 对象(如我所料)。handleChange
:this
是ReactClass.createClass.Constructor
.handleClick
:this
是对Window
对象的引用。
后两者表示状态对象不可用。
非常感谢收到任何建议。
您必须使用 this
绑定方法,因为您不使用自动执行此操作的 React.createClass
。
使用 class 语法的示例:
class Counter extends React.Component {
constructor() {
super();
this.handleChange = this.handleChange.bind(this);
this.handleClick = this.handleClick.bind(this);
}
handleChange() {
...
}
handleClick() {
...
}
}
您必须更改渲染方法:
render() {
// ...
<button onClick={this.handleClick.bind(this)}>Like</button>
<input value={this.state.name} onChange={this.handleChange.bind(this)} />
// ...
}
由于您正在调用事件,因此 this
关键字将更改为事件的默认上下文。
通过使用 .bind(this)
,您确保被调用的上下文将是您的 class.
另一种方法是为事件处理程序使用粗箭头函数,它会自动 "this" 绑定。
handleClick = (evt, domNode):void => {
this.setState({ liked: !this.state.liked, name: this.state.name });
};
<button onClick={() => this.handleClick()}>Like</button>