Фон

Я решил начать новый побочный проект под названием «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 (которая находится внутри текущего компонента).

С помощью этого решения я смог связать одно действие (т.е. отправку ввода) для нескольких компонентов (т.е. компонентов приложения и формы).

Ключевые выводы

Вы можете использовать универсальную функцию обратного вызова для одновременного вызова других функций обратного вызова внутри и вне текущего компонента, который запускает событие. Это приложение также имеет фактор масштабируемости. Если у компонента есть несколько родительских компонентов, на которые все влияет одно и то же событие, универсальная функция обратного вызова может вызывать каждую функцию обратного вызова из соответствующего родительского компонента или своего текущего компонента для выполнения необходимых действий.