Bindowanie funkcji - React - nie rozumiem this

0

Hej!

Mam pytanie odnośnie this w React:

class App extends React.Component{
  constructor(props){
    super(props);

    this.state = {
      users: [],
      loading: false
    }
  }

  submitMethod(e){
    e.preventDefault();
    console.log(this); //dlaczego tu this nie dziala?
  }

  getUsers(){
    console.log(this); // dlaczego tu this dziala?
  }

  componentDidMount(){
    this.setState({loading: true});
    this.getUsers();
  }

  render(){
    return (
     <div className="App">
       {
        this.state.loading ? ( <Loading message="Ładowaniee..." /> ) : (

          <form onSubmit={ this.submitMethod }>
            <input type="text" placeholder="testujemy jolo" />
          </form>
        )
       }
     </div> 
    )
  } 
}

export default App;

Czy może ktoś mi to wytłumaczyć :) ?

1

Tak się ogólnie this zachowuje w js, nie ma to nic wspólnego z reactem, submitMethod jest wywoływana jako callback i jest wykonywana w innym kontekście, więcej tutaj:

Mastering ‘this’ in JavaScript: Callbacks and bind(), apply(), call()

0

W tym przypadku this musisz zrozumieć w ten sposób. Pomyśl, że form jest innym komponentem i twoją funkcję submitMethod wykonuje w swojej klasie

class Form extends Component {
  handleSubmit() {
     // Tutaj wywoła się twoja funkcja, tutaj zaś masz inny kontekst, czyli 'this` będzie kierował do konteksu `Form`
     this.props.submit()
  }
}

Zaś metoda getUsers() jest wywoływana we własnej klasie, więc this będzie kierował do konteksu App

1

Tak jak już wspomnieli koledzy powyżej, to jest zachowanie specyficzne dla samego JS, a nie dla Reacta. Jeżeli potrzebujesz mieć dostęp do this w tej funkcji to wystarczy dowiązać ją do instancji. Możesz to zrobić w konstruktorze:

class App extends React.Component{
  constructor(props){
    super(props);

    this.state = {
      users: [],
      loading: false
    }

    // w konstruktorze wołasz bind(this)
    this.submitMethod = this.submitMethod.bind(this);
  }

  submitMethod(e){
    e.preventDefault();
    console.log(this);
  }
  //dalsza treść klasy bez zmian
}

Inny sposób to deklaracja funkcji jako pole klasy czyli:

class App extends React.Component{
  constructor(props){
    super(props);

    this.state = {
      users: [],
      loading: false
    }
  }

  submitMethod = (e) => {
    e.preventDefault();
    console.log(this);
  }
  //dalsza treść klasy bez zmian
}

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