Pull to refresh

Comments 24

Как альтернатива — можно использовать строковое название и тогда не придется каждый вызов создавать анонимную функцию, не знаю, почему в статье нету этого примера.

class Hello extends React.Component {
  constructor() {
    this.focus = this.focus.bind(this);
  }

  handleClick() {
    this.refs.myTextInput.focus();
  }

  render() {
    return (
      <div>
        <input type="text" ref="myTextInput" />
        <input type="button" value="Focus" onClick={this.focus} />
      </div>
    );
  }
}


edit: таки описано:
Использование обратного вызова ref для установки свойства в классе — это общепринятый шаблон для доступа к элементам DOM. Если в настоящий момент для этой задачи вы используете this.refs.myRefName, мы рекомендуем перейти к использованию описанного нами шаблона.


не хватает аргументов, почему рекомендуют.
В статье об этом написано:
Использование обратного вызова ref для установки свойства в классе — это общепринятый шаблон для доступа к элементам DOM. Если в настоящий момент для этой задачи вы используете this.refs.myRefName, мы рекомендуем перейти к использованию описанного нами шаблона.
Не надо давать уникальные имена универсальным шаблонным элементам, можно использовать универсальные функции. Представьте, что у вас 2 inputa и 2 кнопки. И там и там одинаковый функционал.
Звучит как место для вывода кода в отдельный компонент. Но я не могу понять, что именно вы предлагаете.
Как различать какие элементы демонтируются?
не хватает аргументов, почему рекомендуют.

У меня сложилось впечатление, что это для того, чтобы люди избегали использования ref как таковых, окромя тех ситуаций, когда иначе никак. Может быть с их точки зрения, люди злоупотребляют этой возможностью в ущерб react-way.

Тогда надо сделать depricated, а потом убрать )
Да, если добавить сюда ранее не документированный контекст, dangerouslySetInnerHTML={{ __html: «Hello» }}, вечные предупреждения при управлении div[contenteditable=«true»] — то получится сплошная политика запретов. VUE в этом плане куда свободнее
У меня сложилось впечатление, что это для того, чтобы люди избегали использования ref как таковых, окромя тех ситуаций, когда иначе никак.

И молодцы. Дали теперь возможность таким людям писать что-то вроде такого:

<input ref={(input) => calculateSomething()} />


Архитекторы очень мудры

Вопрос к эксперту: а разве такого рода даже анонимные функции не успешно ли оптимизируются движком и фактически функция заново не создается? Или все же она сразу же выбрасывается из памяти после выполнения render?

Если только с точки зрения теории, то стоит не забывать, что это не просто блок кода, а объект первого класса, он создается, к нему цепляется scope и prototype, его присваивают переменной. Чистые функции легче оптимизировать (там нет необходимости оставлять замыкание), эта функция грязная.

На практике даже самые современные браузеры не всегда очищают память, если на неё была замкнута функция даже если эта функция уже неактуальна (это что-то вроде перекресных ссылок). И тем больше вероятность чем сложнее приложение, а одна неудачная неочищенная ссылка тянет за собой целый ворох мусора. А код реакта как раз крайне нетривиален.

Более того, кроме чисто js-нюансов есть и важная особенность Реакта. Процитирую из документации:
class LoggingButton extends React.Component {
  handleClick() {
    console.log('this is:', this);
  }

  render() {
    // This syntax ensures `this` is bound within handleClick
    return (
      <button onClick={(e) => this.handleClick(e)}>
        Click me
      </button>
    );
  }
}


The problem with this syntax is that a different callback is created each time the LoggingButton renders. In most cases, this is fine. However, if this callback is passed as a prop to lower components, those components might do an extra re-rendering. We generally recommend binding in the constructor or using the property initializer syntax, to avoid this sort of performance problem.


То есть каждую перерисовку LoggingButton внутренний button будет получать НОВЫЙ экземпляр функции и потому Реакт будет считать, что его необходимо обновить, хотя можно было бы использовать закешированный (старый) вариант, если бы экземпляр функции с контекстом был создан и сохранен изначально.

пс. Есть очень хорошая статья, которая поможет понять, что происходит и какая работа выполняется при создании анонимной функции: http://dmitrysoshnikov.com/ecmascript/ru-chapter-6-closures/
То есть каждую перерисовку LoggingButton внутренний button будет получать НОВЫЙ экземпляр функции и потому Реакт будет считать, что его необходимо обновить, хотя можно было бы использовать закешированный (старый) вариант, если бы экземпляр функции с контекстом был создан и сохранен изначально.


Следует понимать что это актуально только если реализовывается shouldComponentUpdate со сравнением функций переданных через props. Стандартная реализация shouldComponentUpdate просто возвращает true, поэтому компоненту глубоко плевать на то, новосозданная это функция или закешированная.

П.С. вот хорошая статья на тему производительности реакта http://blog.csssr.ru/2016/12/07/react-perfomance/
Или если что-то типа Redux/MobX/… подставляет свою функцию, о чём можно даже не догадываться при поверхностном изучении. Второй вариант — несколько этих компонентов на странице, в такой форме будет создаваться новая функция для каждого элемента, а могла бы одна биндиться.
Вот тут участники реакта немного проясняют свою позицию:
There are multiple problems with it:

  • It requires that React keeps track of currently rendering component (since it can't guess this). This makes React a bit slower.
  • It doesn't work as most people would expect with the «render callback» pattern (e.g.
    <DataGrid renderRow={this.renderRow} />
    
    ) because the ref would get placed on DataGrid for the above reason.
  • It is not composable, i.e. if a library puts a ref on the passed child, the user can't put another ref on it (e.g. #8734). Callback refs are perfectly composable.


Кстати, эту информацию уже добавили в официальную доку, неплохо бы наверное и перевод обновить ;-)
Опять невалидное. Почему бы им просто не использовать data-атрибуты. Каждый пытается свою спецификацию сделать…

Дык, эти атрибуты же не добираются до DOM. Это внутренняя кухня.

Если честно просто не пользуюсь реактом(и ангуляром из-за несоблюдения стандартов), но в любом случае этих атрибутом нет в спецификации. Есть data-атрибуты. Вы хотите сказать, что в выхлопе на HTML они урезаются чтоли или переформируются в валидный код?
В Реакте не используется HTML, JSX (JS+XML) не надмножество ни HTML, ни даже xHTML. Как говорится, все элементы и атрибуты XML вымышлены, все совпадения с HTML случайны. JSX-элементы «рендерятся» в вызовы JS-функций CreateElement, которые возвращают элементы виртуального DOM, которые потом «рендерятся» в реальный. HTML в процессе вообще не участвует (серверный рендеринг опустим для простоты), а алгоритм маппинга виртуального DOM на реальный может быть произвольным. Стараются, конечно быть поближе к HTML, но священную корову из него не делают, не просто расширяя или урезая его, но и меняя синтаксис.

В общем и в целом, часть атрибутов передаётся as is, часть переформатируется в валидный код, часть урезается.
Кому надоел React, ставьте плюс. :)
Кому нравиться, пройдите мимо. :)
Просил же пройти мимо.
Нет же, еще и в карму насрало.
На хабре полно людей, никогда не проходящих мимо.

Особенно когда их об этом просишь. Специально не пройдут, ну и в карму специально не поленятся зайти.

Терпите. :-)
Sign up to leave a comment.

Articles