Порядок, в котором вы их вызываете, насколько мне известно, два вызова useEffect в компоненте всегда будут выполняться в одном и том же порядке. Вот как React определяет, какой хук какой (на основе порядка).
Одна из главных вещей, которые вы не можете сделать, - это условно запустить хук по причине, указанной выше: React отслеживает хуки, которые называются на основе по порядку (индексу) они вызываются в компоненте.
Эта цитата говорит о порядке вызовов очистки в компонентах и между родительскими и дочерними компонентами. Как правило, то, что вы делаете в части очистки, не должно влиять на другие хуки. Обычно то, что вы делаете, убирает любой длительный побочный эффект в вашем крючке. Такие вещи, как отмена вызовов API и очистка интервалов.
Мы гарантируем, что родительские эффекты уничтожаются раньше, чем дочерние. Причина этого заключается в том, что родители часто имеют тенденцию зависеть от какого-то ресурса, созданного ребенком. Например, удаление слушателя из DOM-узла, которым обязательно управляет ребенок. Если ребенок сначала удаляет свои ресурсы, родитель, возможно, не сможет должным образом очистить себя. Это не указывается c для хуков - это то, как работает componentWillUnmount.
Мы не даем никаких гарантий относительно порядка родственных элементов, будь то внутри компонента или между братьями и сестрами. Это потому, что сильные гарантии мешают рефакторингу. Внутри компонента вы должны иметь возможность переупорядочивать крючки, особенно пользовательские. Ожидается, что между братьями и сестрами вы также можете безопасно переупорядочить их. Также распространено, что только один брат обновляется или отключается, поэтому зависимости между братьями и сестрами не могут быть надежными в любом случае.
Порядок между родителем и дочерним элементом установлен. Например, родительский компонент, который отображает 2 дочерних элемента.
<Parent>
<Child/>
<Child/>
</Parent>
Редактировать: так я бы реорганизовал ваш код:
Я бы обязательно включил cb в исходный useRef, а затем используйте cb в массиве зависимостей первого эффекта, чтобы обновить ссылку.
Тогда вы обязательно очистите интервал во втором эффекте.
const Comp = ({ handler }) => {
// handler is some callback of the form ( ) => void
useSomeHook(handler);
//...
};
function useSomeHook(cb) {
const ref = useRef(cb);
useEffect(() => {
ref.current = cb; // update ref before second useEffect
},[cb]);
useEffect(() => {
const id = setInterval(() => {
ref.current();
}, 3000); // use the current (most recent) ref value
return () => {
clearInterval(id);
};
}, []); // run only after first render
}