Возможно, вы слышали, что в javascript объекты передаются по ссылке. Это может не иметь смысла, если вы не видите пример. Вместо того, чтобы приводить простой пример этой концепции, я решил прояснить ее в приложении на основе React.

Допустим, у нас есть ввод в нашем компоненте. Мы определяем useState для обновления состояния ввода.

const [name, setName] = useState('');

И у нас есть элемент ввода соответственно:

<input value={name} onChange={(e) => setName(e.target.value)} />

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

Это означает, что хук useEffect имеет зависимость от name. Это будет работать дважды. Сначала он запускается как первоначальный запуск, затем имя будет изменено, и, поскольку useEffect имеет зависимость от этого имени, он будет запущен во второй раз. При втором запуске, поскольку имя такое же, он не запустится в третий раз, если только мы вручную не изменим ввод.

Давайте изменим код на следующий:

В данном случае мы изменили строку 4 со строки на объект. На этот раз при втором запуске он видит, что предыдущее значение было {name: 'Vahid'}, а текущее значение равно {name: 'Vahid'}. Вы можете сказать, что они одинаковые, так что это не будет работать, как в предыдущем примере. Но в javascript они не совпадают. Потому что это сравнение ссылок, а не значений, когда речь идет об объектах. Вы можете это хорошо понять, если увидите следующий пример javascript:

Итак, в нашем реактивном проекте useEffect будет работать всегда.

Следующий пример, который я собираюсь вам привести, касается React.memo и useCallback, чтобы вы могли понять важность этой темы. Рассмотрим следующий код:

Всякий раз, когда реквизит изменяется, все компоненты перерисовываются. Вы можете просто установить console.log в каждом компоненте, чтобы увидеть результат. Основное решение — экспортировать с React.memo в дочерние компоненты.

Если вы протестируете его, вы увидите, что компонент Header больше не перерисовывается. Но кнопочные компоненты есть. Причина в том, что всякий раз, когда этот родительский компонент перерисовывается, он создает новый обработчик функции (например, changeName). На данный момент хотя функциональность та же, но ссылки на функции нет. Таким образом, помимо объектов по ссылке передаются и функции. Затем вы можете использовать хук useCallback. Вот определение хука useCallback:

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

Таким образом, это полезно при передаче обратных вызовов оптимизированным дочерним компонентам (которые React.memo используются при экспорте компонента), которые полагаются на равенство ссылок для предотвращения ненужного рендеринга. Вот результат:

Надеюсь, теперь у вас есть полное представление о концепции передачи по ссылке в javascript.