Другой ответ немного запутан - то, что вы делаете, хорошо. Когда он говорит, что не вызывайте хуки изнутри, это означает, что не вызывайте реальный API условно или из циклов, например условно определяя useEffect
или useState
.
Ваша проблема связана с пустым массивом, который вы передаете эффекту в Observer.js, поскольку он пустой, эффект никогда не обновляется, поэтому замыкание устарело, так что когда функция onResize
вызывает setState
, [ 114] значение всегда будет начальным значением нуля.
Вам необходимо, чтобы useEffect
зависело от чего-либо, чтобы при обновлении компонента он очищал предыдущий эффект и прикреплял новую версию функции onResize
к ResizeObserver.
Я немного поэкспериментировал с вашей песочницей: https://codesandbox.io/s/x9z7k245lq?fontsize=14
Теперь он передает состояние счетчика в компонент Observer. и эффект будет запускаться каждый раз при изменении счетчика. Дело в том, что я также добавил несколько ссылок в индекс, чтобы отслеживать высоту / ширину, чтобы состояние не всегда обновлялось, иначе оно будет бесконечно зацикливаться. Я думаю, вы можете думать об этом как shouldComponentUpdate
.
Нужно некоторое время, чтобы правильно подумать. Если вы хотите прочитать хорошую статью о хуках и избежать некоторых ловушек, касающихся пустых массивов и устаревших замыканий, проверьте это: https://overreacted.io/making-setinterval-declarative-with-react-hooks/ [119 ]
Они плохи тем, что не служат цели. По своей сути интерфейс - это просто контракт на передачу данных. Нет реализации, связанной с интерфейсом, и, следовательно, нет ничего для инициализации и нет необходимости в конструкторе.
Если вам нужна какая-то инициализация, вам лучше использовать абстрактный класс.
Хотя интерфейсы не могут иметь конструкторы в большинстве языков, шаблон фабрики предоставляет контракт на создание объектов, аналогичный интерфейсу. Посмотрите на это.
Независимо от того, плохи они или нет, я не знаю ни одного языка, который мог бы указывать конструктор на интерфейсе.
Однако, как я уже сказал, я лично не верю что конструктор объекта является частью интерфейса этого объекта, и поэтому добавление конструктора к интерфейсу будет препятствовать естественной гибкости, которую предоставляют интерфейсы.
Почему люди думают, что кто-то хочет создать интеграцию интерфейса?
Что мы хотим сделать, это заставить исполнителей реализовать конструктор, как и другие методы интерфейса.
Интерфейс похож на договор. Допустим, у меня есть очередь интерфейсной очереди, и я хочу убедиться, что реализующие создают конструктор с одним аргументом, что создает очередь Singleton (новая очередь только с этим элементом). Почему это должно быть не частью договора? С хотя бы Java интерфейсы, которые не могут быть указаны.
Во-первых, я не согласен, что интерфейс - это просто данный договор. Если это было правдой, вам было бы разрешено определить свойства в интерфейсе.
Я бы точно не думаю, что это странно делать что-то вроде:
interface IDBConnection
{
function __construct( $connectionString );
function executeNonQuery( $commandText, $paramters=null);
function executeScalar( $commandText, $paramters=null);
function executeSingle( $commandText, $paramters=null);
function executeArray( $commandText, $paramters=null);
}
Это позволило бы вам создать экземпляры занятий третьей сторонними классами для доступа к данным на основе простого отражения вместо того, чтобы просто быть договором к данным.
Я уверен, что это не самый лучший пример, я бы пошел на абстрактный базовый класс здесь в реальном мире, но я также уверен, что есть совершенно действительные причины определения методов конструктора «Договор в интерфейсе, о котором я не думал.
Я не видел это, но я бы не думал, что это странно или плохо.