Я читал кучу react
кода, и я вижу такие вещи, которые я не понимаю:
handleChange = field => e => {
e.preventDefault();
/// Do something here
}
Я читал кучу react
кода, и я вижу такие вещи, которые я не понимаю:
handleChange = field => e => {
e.preventDefault();
/// Do something here
}
Ответы:
Это функция карри
Сначала рассмотрим эту функцию с двумя параметрами ...
Вот оно снова в карри ...
Вот тот же код 1 без функций стрелок ...
Сосредоточиться на
return
Это может помочь визуализировать это по-другому. Мы знаем, что функции стрелок работают так - давайте обратим особое внимание на возвращаемое значение .
Таким образом, наша
add
функция возвращает функцию - мы можем использовать скобки для большей ясности. Текст, выделенный жирным шрифтом, является возвращаемым значением нашей функции.add
Другими словами,
add
некоторое число возвращает функциюВызов карри функций
Таким образом, чтобы использовать нашу функцию карри, мы должны вызвать ее немного по-другому ...
Это потому, что первый (внешний) вызов функции возвращает вторую (внутреннюю) функцию. Только после вызова второй функции мы действительно получаем результат. Это станет более очевидным, если мы разделим звонки на две строки ...
Применяя наше новое понимание к вашему коду
Хорошо, теперь, когда мы понимаем, как это работает, давайте посмотрим на ваш код
Мы начнем с представления его без использования функций стрелок ...
Однако, поскольку функции со стрелками лексически связываются
this
, это на самом деле выглядеть следующим образом ...Может быть, теперь мы можем видеть, что это делает более четко.
handleChange
Функция создания функции для указаннойfield
. Это удобный метод React, потому что вам необходимо настроить своих собственных слушателей на каждом входе, чтобы обновить состояние ваших приложений. ИспользуяhandleChange
функцию, мы можем устранить весь дублированный код, который приведет к настройкеchange
прослушивателей для каждого поля. Круто!1 Здесь мне не нужно было лексически связывать,
this
потому что исходнаяadd
функция не использует никакого контекста, поэтому не важно сохранять ее в этом случае.Еще больше стрел
При необходимости можно упорядочить более двух функций стрелок:
Функции карри способны на удивительные вещи. Ниже мы видим
$
определенную как карри функцию с двумя параметрами, но на сайте вызова она выглядит так, как будто мы можем предоставить любое количество аргументов. Карри - это абстракция арности -Частичное применение
Частичное применение является связанной концепцией. Это позволяет нам частично применять функции, похожие на карри, за исключением того, что функция не должна быть определена в форме карри -
Вот рабочая демонстрация того, что
partial
вы можете играть в своем браузере -источник
$
использовался для демонстрации концепции, но вы можете назвать ее как хотите. По совпадению , но совершенно не связаны,$
уже используются в популярных библиотек , как JQuery, где$
является своего рода глобальной точки входа целой библиотеки функций. Я думаю, что это использовалось и в других. Другое, что вы увидите_
, популяризируется в библиотеках, таких как подчеркивание и lodash. Ни один символ не является более значимым, чем другой; Вы назначаете значение для вашей программы. Это просто правильный JavaScript: D$
, взглянув на то, как оно используется. Если вы спрашиваете о самой реализации,$
это функция, которая получает значениеx
и возвращает новую функциюk => ...
. Глядя на тело возвращаемой функции, мы видим,k (x)
что мыk
также должны знать, что она должна быть функцией, и что бы ниk (x)
возвращалось в результат$ (...)
, то, что мы знаем, возвращает другоеk => ...
, и это продолжается ... Если вы все еще застрять, дайте мне знать.abc(1,2,3)
менее чем идеальноabc(1)(2)(3)
. Труднее рассуждать о логике кода, трудно прочитать функцию abc и сложнее прочитать вызов функции. Раньше вам нужно было только знать, что делает abc, теперь вы не уверены, что делают неназванные функции, которые возвращает abc, и дважды.Понимание доступных синтаксисов функций стрелок даст вам понимание того, какое поведение они вводят, когда они «цепочки», как в приведенных вами примерах.
Когда функция стрелки написана без фигурных скобок, с несколькими параметрами или без них, неявно возвращается выражение, составляющее тело функции . В вашем примере это выражение является еще одной функцией стрелки.
Другое преимущество написания анонимных функций с использованием синтаксиса стрелок состоит в том, что они лексически связаны с областью, в которой они определены. Из «Стрелка функций» на MDN :
Это особенно уместно в вашем примере, учитывая, что оно взято из reactjsприменение. Как отмечает @naomik, в React вы часто получаете доступ к функциям-членам компонента, используя
this
. Например:источник
Общий совет: если вас смущает какой-либо новый синтаксис JS и способ его компиляции, вы можете проверить babel . Например, копирование кода в babel и выбор предустановки es2015 приведут к следующему выводу
источник
Думайте об этом так, каждый раз, когда вы видите стрелку, вы заменяете ее
function
.function parameters
определяются перед стрелкой.Итак, в вашем примере:
а потом вместе:
Из документов :
источник
this
.Кратко и просто 🎈
Это функция, которая возвращает другую функцию, написанную кратко.
Почему люди это делают?
Сталкивались ли вы когда вам нужно написать функцию, которую можно настроить? Или вам нужно написать функцию обратного вызова, которая имеет фиксированные параметры (аргументы), но вам нужно передать больше переменных в функцию, но избегая глобальных переменных? Если ваш ответ « да », то это способ, как это сделать.
Например, у нас есть
button
обратный вызов onClick. И нам нужно перейтиid
к функции, ноonClick
принимает только один параметрevent
, мы не можем передать дополнительные параметры, как это:Он не будет работать!
Поэтому мы создаем функцию, которая будет возвращать другую функцию с собственным диапазоном переменных без каких-либо глобальных переменных, потому что глобальные переменные являются злом 😈.
Ниже функция
handleClick(props.id)}
будет вызываться и возвращать функцию, и она будет иметьid
в своей области видимости! Независимо от того, сколько раз он будет нажат, идентификаторы не будут влиять или изменять друг друга, они полностью изолированы.источник
Примером в вашем вопросе является тот,
curried function
который используетarrow function
и имеетimplicit return
для первого аргумента.Функция Arrow связывает это с лексической точки зрения, т. Е. У них нет собственного
this
аргумента, но она принимаетthis
значение из окружающей области видимости.Эквивалентом приведенного выше кода будет
Еще одна вещь, которую стоит отметить в вашем примере, это определить
handleChange
как const или функцию. Возможно, вы используете его как часть метода класса, и он используетclass fields syntax
поэтому вместо того, чтобы связывать внешнюю функцию напрямую, вы должны связать ее в конструкторе класса
Еще одна вещь, которую следует отметить в этом примере, - это разница между неявным и явным возвратом.
Выше приведен пример неявного возврата т.е. он принимает поле значения в качестве аргумента и возвращает результат
field*2
который явно указывает возвращаемую функциюДля явного возврата вы бы явно указали методу вернуть значение
Еще одна вещь, которую следует отметить в отношении функций стрелок, заключается в том, что они не имеют своих собственных функций,
arguments
но также наследуют их от родительской области.Например, если вы просто определите функцию стрелки, как
В качестве альтернативы функции стрелки предоставляют остальные параметры, которые вы можете использовать
источник
Возможно, это не совсем связано, но поскольку в упомянутом вопросе «реакция» используется регистр (и я продолжаю сталкиваться с этим потоком SO): есть один важный аспект функции двойной стрелки, который здесь явно не упоминается. Только «первая» стрелка (функция) получает имя (и, следовательно, «различима» во время выполнения), любые последующие стрелки являются анонимными и с точки зрения React считаются «новым» объектом при каждом рендеринге.
Таким образом, функция двойной стрелки будет вызывать повторное отображение любого PureComponent.
пример
У вас есть родительский компонент с обработчиком изменений как:
и с рендером, как:
{ tasks.map(task => <MyTask handleChange={this.handleChange(task)}/> }
Затем handleChange используется для ввода или щелчка. И все это работает и выглядит очень красиво. НО это означает, что любое изменение, которое вызовет повторную визуализацию родителя (например, совершенно не связанное изменение состояния), будет также повторно отображать ВСЕ ваши MyTask, даже если они являются PureComponents.
Это может быть облегчено многими способами, такими как передача стрелки 'outmost' и объекта, которым вы бы ее подали, или написание пользовательской функции shouldUpdate или возвращение к основам, таким как написание именованных функций (и связывание этого вручную ...)
источник