react create cli app adding typescript reactjs react-jsx

create - react cli typescript



Reaccionar a los controladores de eventos con Typescript y JSX (3)

Tengo problemas para actualizar el estado en un componente React que estoy escribiendo en TypeScript (React with Addons 0.13.3, Typescript 1.6.0-dev.20150804, archivo de definición de 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;

El código de llamada es

/// <reference path="react/react-addons.d.ts" /> import React = require("react/addons"); import App = require("app"); React.render(App({}), document.getElementById("jsapp"));

El componente se procesa como yo esperaría, pero los métodos handleClick y handleChange no actualizan el estado correctamente. Si pongo puntos de interrupción en esos dos métodos y render veo los siguientes valores para this :

  • render : this es un objeto Tester (lo que esperaría).
  • handleChange : this es un ReactClass.createClass.Constructor .
  • handleClick : this es una referencia al objeto Window .

Los dos últimos significan que el objeto de estado no está disponible.

Cualquier sugerencia recibida con gratitud.


Debes cambiar tu método de render:

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

Como está llamando a un evento, this palabra clave se cambiará al contexto predeterminado del evento. Al usar .bind(this) se asegura de que el contexto al que se llama sea la instancia de su clase.


Otro método es utilizar las funciones de flecha gruesa para los controladores de eventos que obtienen el enlace automático "this".

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


React.createClass vincular los métodos con this porque no utiliza React.createClass que lo hace automáticamente. Ejemplo con una sintaxis de clase:

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