React set Hook из вызова функции вне компонента

Я тестирую новые React Hooks и столкнулся с поведением, которое не могу исправить (и не понимаю ни того, ни другого). По сути, у меня есть свой функциональный компонент и внутри него функция, в которой я устанавливаю хук. Эта функция передается отображаемому компоненту и вызывается из этого последнего визуализированного компонента с использованием свойств. Жаль, что хуки родителя не обновляются соответственно!

Я знаю, что это может показаться трудным для понимания, но я воспроизвел здесь ошибку https://codesandbox.io/s/vvwp33l7o5

Как видите, в компоненте App у меня есть функция onResize, которая должна обновлять хук counter. Эта функция передается компоненту ResizeObserverContainerHook и из последнего вызывается при изменении размера ResizeObseverContainerHook div. Как видите, переменные width и height в функции onResize верны, но хук counter не обновляется! Фактически, он остается равным 1 навсегда.

Я не знаю, похоже, я не могу обновить хук из-за пределов Компонента (и это похоже на состояние в React Stateful Component, но, по крайней мере, я мог бы передать функцию, как в этом случае, но это не работает :/ ).

Любая идея, как я могу заставить это setCounter работать примерно на 12 из index.js?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
11 715
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Другой ответ немного смущен - то, что вы делаете, в порядке. Когда говорится, что нельзя вызывать хуки изнутри, это означает, что фактический API не следует вызывать условно или из циклов, например. условно определяя useEffect или useState.

Ваша проблема связана с пустым массивом, который вы передаете эффекту в Observer.js, потому что он пуст, эффект никогда не обновляется, поэтому закрытие устарело, поэтому, когда функция onResize вызывает setState, значение counter всегда будет начальным значением нуля.

Вам нужно, чтобы этот useEffect зависел от чего-то, чтобы при обновлении компонента он очищал предыдущий эффект и присоединял новую версию функции onResize к ResizeObserver.

Я немного поковырялся в вашей песочнице: https://codesandbox.io/s/x9z7k245lq?fontsize=14

Теперь он передает состояние счетчика компоненту Observer, и эффект будет выполняться каждый раз при изменении счетчика. Дело в том, что я также добавил некоторые ссылки в индекс для отслеживания высоты/ширины, поэтому состояние не всегда обновляется, иначе оно будет бесконечно зацикливаться. Я думаю, вы можете думать об этом как shouldComponentUpdate.

Требуется некоторое время, чтобы правильно мыслить крючками. Если вы хотите прочитать хорошую статью о ловушках и избежать некоторых ловушек, связанных с пустым массивом и устаревшими замыканиями, проверьте это: https://overreacted.io/making-setinterval-declarative-with-react-hooks/

Хм, теперь это имеет больше смысла! Но.. Можно ли не переходить counter в Observer? Observer должен быть более общим компонентом, он должен просто запускать функцию, когда его div элемент изменяется. Затем, как правило, эта функция обновляет состояние компонента, который отображает Observer.

Jolly 05.03.2019 23:13

О да, я думаю, вы могли бы просто полностью не передавать counter, на самом деле он ничего не делает, поэтому вы могли бы просто не передавать второй аргумент useEffect - я просто пытался избежать пустого []. Что нужно знать об этой реализации, так это то, что в настоящее время она не зацикливается бесконечно, потому что проверка ширины/высоты в функции onResize.

Tom Finney 06.03.2019 09:54

Да, мне потребовалось некоторое время, чтобы понять, что значения в эффектах/обратных вызовах могут быть устаревшими, несмотря на то, что они, похоже, напрямую ссылаются на состояние. Я нашел тот блог, на который я ссылался, действительно полезным для расширения моего понимания того, почему все работает не так, как я ожидал.

Tom Finney 06.03.2019 17:32

Другие вопросы по теме