diff --git a/hooks/src/index.js b/hooks/src/index.js index 6af5611123..57cfcbc50d 100644 --- a/hooks/src/index.js +++ b/hooks/src/index.js @@ -331,7 +331,11 @@ function afterPaint(newQueueLength) { * @param {import('./internal').EffectHookState} hook */ function invokeCleanup(hook) { + // A hook cleanup can introduce a call to render which creates a new root, this will call options.vnode + // and move the currentComponent away. + const comp = currentComponent; if (typeof hook._cleanup == 'function') hook._cleanup(); + currentComponent = comp; } /** @@ -339,7 +343,11 @@ function invokeCleanup(hook) { * @param {import('./internal').EffectHookState} hook */ function invokeEffect(hook) { + // A hook call can introduce a call to render which creates a new root, this will call options.vnode + // and move the currentComponent away. + const comp = currentComponent; hook._cleanup = hook._value(); + currentComponent = comp; } /** diff --git a/hooks/test/browser/useEffect.test.js b/hooks/test/browser/useEffect.test.js index 4aca911e47..a16d3fc1ec 100644 --- a/hooks/test/browser/useEffect.test.js +++ b/hooks/test/browser/useEffect.test.js @@ -1,7 +1,7 @@ import { act } from 'preact/test-utils'; import { createElement, render, Fragment, Component } from 'preact'; +import { useEffect, useState, useRef } from 'preact/hooks'; import { setupScratch, teardown } from '../../../test/_util/helpers'; -import { useEffect, useState } from 'preact/hooks'; import { useEffectAssertions } from './useEffectAssertions.test'; import { scheduleEffectAssert } from '../_util/useEffectUtil'; @@ -320,4 +320,54 @@ describe('useEffect', () => { render(