Вызов функции в обработчике событий возвращает желаемые результаты, но ссылка на метод не - PullRequest
0 голосов
/ 05 июля 2019

Мне очень тяжело понять это ключевое слово и то, как оно работает в отношении реакции.Я знаю правильный ответ на мою проблему, но я не понимаю ПОЧЕМУ это работает, а другие мои решения нет.this.showTime.bind(this) сообщает методу showTime использовать объект Contact, как в методе showTime.(если это не часть моего недоразумения).

Вот мой код с несколькими примерами различий.

import React from 'react';
import Users from './Users.js';

class Contact extends React.Component {
constructor() {
    super();
    this.state = {};
    this.showTime = this.showTime.bind(this); // correct solution
}

showTime() {
    console.log(this.state);
    console.log('tom');
};



render(){
    const { name, email, phone } = this.props;

        return (
            <div>
                {console.log(this)}
                <h4> onClick ={this.showTime} className="click">click me</h4>
                // WORKS BUT THIS.STATE IS UNDEFINED
                <h4> onClick ={this.showTime()} className="click">click me</h4>
                // WORKS
                <h4> onClick ={contact.prototype.showTime} className="click">click me</h4>
                // WORKS BUT THIS.STATE IS UNDEFINED
                <h4> onClick ={this.showTime.bind(Contact)} className="click">click 
                    me</h4>
                // WORKS BUT THIS.STATE IS UNDEFINED
                <h4>email: {email}</h4>
                <h4>phone: {phone}</h4>
            </div>
        );
    }
}

export default Contact;

Почему вызов функции в обработчике дает мне желаемые результаты по сравнению с this.showTime?Ключевое слово

Logging this внутри рендера возвращает объект Contact, поэтому теоретически Contact.prototype.showTime.bind(Contact) или this.showTime.bind(Contact) должно работать, но это не так.

Я знаю, что ключевое слово thisне имеет области видимости и теряет контекст при вложении.Это строго определено в контексте класса, поэтому оно не возвращает объект окна.Я просто не могу понять, что мне здесь не хватает.

1 Ответ

0 голосов
/ 05 июля 2019

Похоже, у вас есть несколько преждевременно закрытых тегов h4 в вашем примере, но я предполагаю, что это просто опечатки. Кроме того, вот некоторые заметки, которые могут помочь:

  • <h4 onClick={this.showTime}> - 'this' должен правильно вызывать и регистрировать состояние, если у вас есть привязка showTime в конструкторе, или вместо этого вы также можете использовать функцию стрелки ES6 для ее привязки: showTime = () => {...}

  • <h4> onClick={this.showTime()}> - 'this' правильно ссылается на showTime, но вызывает его немедленно, а не onClick. Вы можете использовать <h4> onClick={() => this.showTime()}>, чтобы позволить вызывать его onClick, но писать его таким образом не нужно в этом случае, так как никакие аргументы не передаются, и вы уже связали showTime в конструкторе. Преимущество использования функции со стрелкой в ​​строке, как это, заключается в том, что это еще один способ связать функцию, не связывая ее в конструкторе

  • <h4> onClick={Contact.prototype.showTime}> - Я полагаю, что это (контакт с заглавной буквой C) должно правильно указывать на то, где showTime существует в цепочке прототипов, но я думаю, что тогда на него не ссылаются по отношению к экземпляру компонента Contact.

  • <h4> onClick={this.showTime.bind(Contact)} - если вы замените Contact на 'this', он должен работать как положено (обратите внимание, что это приемлемый способ связывания, но он может вызвать некоторые проблемы с производительностью). Я не уверен, зачем вызывать его, так как он у вас вызывает запуск showTime, но показывает неопределенное состояние. Это может иметь какое-то отношение к тому, что React делает за сценой. Когда я записываю «this» из showTime во время его вызова, как у вас, консоль показывает класс Contact, связанный с Webpack.

Извините, у меня нет более четких ответов о том, что происходит за кулисами с 3-м и 4-м примерами, но если вы действительно не любопытны и не хотите знать, почему они работают таким образом, я бы об этом не беспокоился слишком много и просто придерживайтесь предписанных способов связывания в React. Вот хорошая статья, показывающая различные методы: https://www.freecodecamp.org/news/react-binding-patterns-5-approaches-for-handling-this-92c651b5af56/

...