Это происходит потому, что useEffect
выполняет свой обратный вызов после каждого цикла рендеринга, т.е. он выполняется как после первого рендера, так и после каждого обновления.Таким образом, для каждого первого полученного сообщения он открывает новое соединение WebSocket и сохраняет данные в состоянии, которое вызывает цикл.
Подробнее об useEffect можно прочитать здесь
Отредактировано: -
useEffect(() => {
initWebsocket();
}, [orders, subscription]);
Необязательный второй аргумент useEffect
используется для определения, изменилось ли что-либо или нет (в основном он сравнивает прежнее состояние / реквизиты и данное состояние / реквизиты) и вызывает эффектвсякий раз, когда происходит изменение стоимости.
Таким образом, при каждом обновлении состояния orders
этот эффект вызывается и, в свою очередь, вызывает цикл.
Решение: -
Нов вашем случае вы хотите установить соединение WebSocket только один раз после монтирования компонента и продолжать прослушивать входящие данные независимо от состояния или изменения параметров.Вы можете передать пустой [], чтобы он вызывался только один раз при монтировании и размонтировании.
useEffect(() => {
initWebsocket();
// cleanup method which will be called before next execution. in your case unmount.
return () => {
ws.close
}
}, []);
Из документа: -
Это требование достаточно распространено для его построенияв useEffect Hook API.Вы можете указать React пропустить применение эффекта, если определенные значения не изменились между повторными рендерингами.Для этого передайте массив в качестве необязательного второго аргумента для useEffect.
Если вы хотите запустить эффект и очистить его только один раз (при монтировании и размонтировании), вы можете передать пустой массив ([]) в качестве второго аргумента.Это говорит React, что ваш эффект не зависит от каких-либо значений из реквизита или состояния, поэтому его не нужно повторно запускать.Это не обрабатывается как особый случай - это следует непосредственно из того, как всегда работает массив зависимостей.
Если вы передадите пустой массив ([]), реквизиты и состояние внутри эффекта всегда будут иметь свои начальные значения.ценности.Хотя передача [] в качестве второго аргумента ближе к знакомой ментальной модели componentDidMount и componentWillUnmount, обычно есть лучшие решения, позволяющие избежать слишком частого повторного запуска эффектов.