Фон
Я решил начать новый побочный проект под названием «Group Randomizer». Вдохновением для этого послужило то, что когда мы с друзьями разбивались на группы, будь то спорт, видеоигры, парное программирование и т. Д., Мы не знали, как разделиться (ууу, крик за нерешительность!). Я решил, что самый справедливый способ - это рандомизация. Раньше мы писали совпадающие числа на листах бумаги, складывали их, бросали все в шляпу и случайным образом выбирали полоски бумаги (немного смущаясь, чтобы признать, как долго мы это делаем с учетом сегодняшних технологий), пока все не сгруппировались.
Как и в любом другом проекте, я столкнулся с первой проблемой, которая также проверила мое понимание одного из основных принципов Javascript.
Начальная точка группового рандомизатора
Прежде чем приступить к проблеме, давайте воссоздадим ее. Суть ниже - это отправная точка приложения Group Randomizer.
Суть в двух функциях и форме. handleOptionInput
необходимо, чтобы компонент приложения был управляемым, в то время как handleOptionSubmit
добавляет ввод в список параметров пользователя (т. Е. options
).
Как и любое правильное, хорошо структурированное приложение React, нужно всегда разбивать на компоненты. Именно во время этого процесса составления компонентов я наткнулся на свою первую загвоздку. Как вы, наверное, догадались, я хотел разбить форму на компоненты.
Бегство в корягу
В приведенной ниже таблице показан код для компонентов приложения и формы.
Часть логики и переменных были перенесены из исходного компонента приложения в новый компонент формы. Я сохранил функцию handleOptionSubmit
в компоненте приложения, потому что после отправки ввода я хочу добавить ее в список параметров пользователя. Список параметров будет изменен по мере необходимости, когда я продолжу работу над кодом. Компоненту формы не нужно знать текущий список параметров, поскольку его единственная обязанность - обрабатывать ввод.
Если вы не заметили, если вы попытаетесь запустить код из двух сущностей, форма не будет очищена сразу после ее отправки. Это потому, что я не переносил код, чтобы очистить форму после отправки. Вот где я наткнулся на свою загвоздку.
Обычно формы очищаются после отправки, что означает, что они должны быть в handleOptionSubmit
в компоненте приложения. Однако setInput("")
(т.е. очистка формы) вызовет неопределенную ошибку, потому что ловушка [ input, setInput ]
находится в компоненте формы.
Если я попытаюсь поместить setInput("")
в компонент формы, логичным будет поместить его в прослушиватель событий onSubmit
, поскольку я буду очищать его после отправки. Проблема в том, что onSubmit
уже принимает функцию обратного вызова handleOptionSubmit
от родительского компонента (т. Е. App.js).
Напоминание: функции обратного вызова
Прежде чем я углублюсь в свое решение проблемы, давайте сделаем быстрый шаг назад, чтобы освежить в памяти функции обратного вызова. Вот где приходит понимание одного из основных принципов Javascript.
Согласно документации MDN по callback-функциям:
Функция обратного вызова - это функция, переданная в другую функцию в качестве аргумента, которая затем вызывается внутри внешней функции для выполнения какой-либо процедуры или действия.
Если чтения документа MDN недостаточно, прочтите этот блог, который я нашел в отношении функций обратного вызова.
Теперь, когда эта концепция свежа в нашей голове, давайте вернемся к коду.
Функция обратного вызова других функций обратного вызова
Давайте создадим функцию с именем clearOptionInput
, которая очищает поле ввода. Поскольку компонент приложения не знает о переменной input
, функция clearOptionInput
должна находиться в компоненте формы.
В React родительский компонент передает информацию своему дочернему компоненту через свойства, а дочерний компонент передает информацию своему родительскому компоненту через функцию обратного вызова. Если вам также нужно быстро освежить в памяти эту концепцию React, я настоятельно рекомендую прочитать этот блог. Хотя блог в основном посвящен аспекту функции обратного вызова React, он дает хороший обзор того, как информация передается между родительскими и дочерними компонентами.
Как я упоминал ранее, поскольку я поместил функцию очистки ввода в компонент Form, теперь проблема заключается в том, как вызвать пост-отправку функции очистки ввода. После долгих размышлений о том, как связать функцию handleOptionSubmit
, функцию clearOptionInput
и прослушиватель событий onSubmit
, в моей голове возникло решение.
В React прослушиватель событий принимает функцию обратного вызова, которая находится либо в текущем компоненте, либо в его родительском компоненте. Обычно объем этих функций обратного вызова строго находится в пределах соответствующего компонента. Но как насчет функции обратного вызова, которая вызывает другие функции обратного вызова, находящиеся внутри И вне его текущего компонента? Я собираюсь распечатать это следующим образом:
В сущности выше я создал новую функцию под названием clearAndSubmitInput
. Эта функция является функцией обратного вызова, которая будет вызывать функции обратного вызова вне и внутри текущего компонента. В теле функции clearAndSubmitInput
в ее обязанности входит вызов двух других функций: handleOptionSubmit
(т. Е. Функция обратного вызова вне текущего компонента) и clearCallback
(т. Е. Функция обратного вызова внутри текущего компонента). Хотя сначала это не совсем ясно, аргумент clearCallback
используется для того, чтобы функция clearOptionInput
была функцией обратного вызова.
Теперь, когда у меня есть функция clearAndSubmitInput
, я могу использовать ее как функцию обратного вызова для прослушивателя событий onSubmit
. Когда я использую его как функцию обратного вызова, я теперь могу передать функцию clearOptionInput
в качестве аргумента, отвечающего за очистку поля ввода.
По сути, начиная с прослушивателя событий onSubmit
, существует функция обратного вызова (1) функции обратного вызова (2) двух функций обратного вызова (3). Функция обратного вызова (1) - это анонимная функция обратного вызова для самого прослушивателя событий onSubmit
. Функция обратного вызова (2) - это функция clearAndSubmitInput
. Две функции обратного вызова (3) - это функция handleOptionSubmit
(которая находится вне текущего компонента) и функция clearOptionInput
(которая находится внутри текущего компонента).
С помощью этого решения я смог связать одно действие (т.е. отправку ввода) для нескольких компонентов (т.е. компонентов приложения и формы).
Ключевые выводы
Вы можете использовать универсальную функцию обратного вызова для одновременного вызова других функций обратного вызова внутри и вне текущего компонента, который запускает событие. Это приложение также имеет фактор масштабируемости. Если у компонента есть несколько родительских компонентов, на которые все влияет одно и то же событие, универсальная функция обратного вызова может вызывать каждую функцию обратного вызова из соответствующего родительского компонента или своего текущего компонента для выполнения необходимых действий.