Pesquisa de site

javascript - avisos de escopo/setState em React e TS


Eu tenho um aplicativo react/redux bastante simples (repositório completo). Basicamente, eu tenho um formulário web simples com um par de manipuladores onChange. Ambos estão gerando o mesmo aviso;

Aviso: setState(...): Só é possível atualizar um componente que está montado ou sendo montado. Isso geralmente significa que você chamou setState() em um componente desmontado.

O próprio componente é trivial - eu colei o código abaixo. Eu usei a sintaxe TS anônima()=>{} para contornar o escopo de this.

Por algum motivo, quando eu faço log de this em componentDidMount, ele aparece com _reactInternalInstance=ReactCompositeComponentWrapper. O this logado no handler onChange não tem essa propriedade.

Igualmente estranho, __proto__ de this em componentDidMount é Login (como esperado), mas no manipulador de callback, é ReactComponent.

Ambos me levam a acreditar que, de fato, é uma questão de escopo, mas eu não consigo ver de jeito nenhum onde estou errando. Alguém já viu isso antes?

import * as React from 'react';
import {connect} from 'react-redux';
import {FormControl, Button} from 'react-bootstrap';
import {IAppState} from '../store/IAppState';
import AuthActions from '../actions/AuthActions';

interface ILoginProps {
}
interface ILoginState {
    username: string;
    password: string;
}

export class Login extends React.Component<ILoginProps, ILoginState> {
    static propTypes = {};
    state = {
        username: '',
        password: ''
    };

    componentDidMount() {
        console.log('mounted');
        console.log(this);
    }

    usernameChange = (event: any): void => {
        console.log(this);
        this.setState({
            username: event.target.value,
            password: this.state.password
        });
    }

    passwordChange = (event: any): void => {
        this.setState({
            username: this.state.username,
            password: event.target.value
        });
    }

    login = (event: any): void => {
        event.preventDefault();
        console.log('login');
        console.log(this.state);
    }

    render() {
        return (
            <p>
                LOGIN
                <FormControl
                    type='text'
                    value={this.state.username}
                    placeholder='username'
                    onChange={this.usernameChange}
                />
                <FormControl
                    type='text'
                    value={this.state.password}
                    placeholder='password'
                    onChange={this.passwordChange}
                />
                <Button bsStyle='primary' onClick={this.login}>+</Button>
            </p>
        );
    }
}

export function mapStateToProps(state: IAppState) {
    return {};
}

export default connect(mapStateToProps, AuthActions)(Login);