[TypeScript + React] - jak prawidłowo używać ref'ów

0

Cześć,
Uczę się reacta i napotkałem na problem. Mianowicie po kliknięciu w button chciałbym odczytać value z inputa.

Robię to w taki sposób:

import React, {Component, Ref} from 'react';

export default class Start extends Component {

    private playerOneRef: Ref<HTMLInputElement>;
    private playerTwoRef: Ref<HTMLInputElement>;

    constructor(props: any) {
        super(props);
        this.playerOneRef = React.createRef();
        this.playerTwoRef = React.createRef();
    }

    handleClick() {
        console.log(this.playerOneRef)
    }
    
    render() {
        return(
            <div>
                <input type="text" ref={this.playerOneRef} />
                <input type="text" ref={this.playerTwoRef} />
                <button onClick={this.handleClick}>
                    Click
                </button>
            </div>
        );
    }
}

Niestety, przy takim podejściu dostaję error że jest undefined (nie to że deklaruję w konstruktorze). Próbowałem jeszcze ustawiać to przez callback, wtedy również dostaję undefined. Jak to poprawnie zrobić w typescript'cie?

1

dodaj to w konstruktoerze

  this.handleClick = this.handleClick.bind(this);
2

Albo użyj class properties

handleClick = () => {
  console.log(this.playerOneRef)
}

zamiast

handleClick() {
  console.log(this.playerOneRef)
}
0

Dziękuję panowie za pomoc. Ale chciałbym dopytać jeszcze o różnice. Tz użycie arrow function zmienia jakoś scope czy jak? Zawsze myślałem że w ts deklaracja metody przez methodName() jest równoważna z javascriptowym methodName = () => {}.

1

Rada na przyszłość - wszystko kwestionuj, niczego nie zakładaj. Jak widzisz, że this.playerOneRef jest undefined, to sprawdź, czym jest this, bo wtedy byś sam doszedł, że problemem jest to, że this wcale nie jest takie jakie myślisz, że jest , a nie "jak prawidłowo używać refów" (co okazało się błędnym założeniem, bo problem był gdzie indziej, w ogóle nie związany z Reactem, tylko z tym, jak działa JavaScript jako taki).

ukryte założenia, które mamy podczas kodzenia i nieumiejętność kwestionowania tych założeń = problemy.

swoją drogą czym jest this w takim przypadku? Zapewne window albo undefined, ale które z nich? (to zależy, czy masz ustawiony strict mode):
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

1
NickOver napisał(a):

Dziękuję panowie za pomoc. Ale chciałbym dopytać jeszcze o różnice. Tz użycie arrow function zmienia jakoś scope czy jak? Zawsze myślałem że w ts deklaracja metody przez methodName() jest równoważna z javascriptowym methodName = () => {}.

Metoda zdefiniowana w sposób strzałkowy jest tworzona dla każdej instancji klasy (fieldy klasy sa zawsze dostępne w jej kontekście, tak samo jak po wykorzystaniu “bind”). Metoda zdefiniowana w sposób defaultowy, dziala bezpośrednio gdy jest wywolana w kontekście klasy (ma wtedy dostęp do jej fieldów), ale w przypadku wyciagniecia jej poza kontekst traci ten “dostęp”.

Aby dowiedzieć się więcej poczytaj o “babel proposal class properties”.

1 użytkowników online, w tym zalogowanych: 0, gości: 1