2015-08-12 24 views
14

Tôi đang gặp sự cố khi cập nhật trạng thái trong thành phần React Tôi đang viết bằng TypeScript (React with Addons 0.13.3, Typescript 1.6.0-dev.20150804, tệp định nghĩa từ http://definitelytyped.org/).Xử lý sự kiện phản ứng với Typescript và JSX

/// <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; 

Mã gọi là

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

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

Thành phần ám như tôi mong chờ nhưng handleClickhandleChange phương pháp này không cập nhật trạng thái chính xác. Nếu tôi đặt breakpoint trong hai phương pháp và render sau đó tôi nhìn thấy các giá trị sau cho this:

  • render: this là một đối tượng Tester (những gì tôi mong đợi).
  • handleChange: thisReactClass.createClass.Constructor.
  • handleClick: this là tham chiếu đến đối tượng Window.

Hai điều sau có nghĩa là đối tượng trạng thái không khả dụng.

Bất kỳ đề xuất nào được biết ơn.

Trả lời

7

Bạn phải thay đổi phương pháp làm cho bạn:

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

Vì bạn đang gọi điện thoại một sự kiện, từ khóa this sẽ được thay đổi bối cảnh mặc định của sự kiện. Bằng cách sử dụng .bind(this) bạn đảm bảo rằng ngữ cảnh được gọi sẽ là trường hợp của lớp học của bạn.

+7

Lưu ý rằng, trong khi liên kết trong kết xuất hoạt động, nó gây ra vấn đề về hiệu suất. https://medium.com/@esamatti/react-js-pure-render-performance-anti-pattern-fb88c101332f#9bed –

+0

@CraigWalker đọc lớn. Trong thực tế, tôi thường sử dụng các thuộc tính lớp với các hàm mũi tên để tạo các hàm ràng buộc của tôi, nhưng bạn hoàn toàn đúng khi nói về ví dụ được đưa ra trong câu trả lời này! :) – Buzinas

+0

Bạn không nên ràng buộc trong phương thức 'render', ràng buộc phải được thực hiện trong hàm tạo, ràng buộc trong render sẽ tạo ra một hàm mới tại mỗi render. –

10

Bạn phải liên kết các phương thức với this vì bạn không sử dụng React.createClass tự động thực hiện. Ví dụ với một cú pháp lớp:

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

Một phương pháp khác là sử dụng chức năng mũi tên chất béo cho trình xử lý sự kiện có liên kết "này" tự động.

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

<button onClick={() => this.handleClick()}>Like</button> 
Các vấn đề liên quan