Skip to content

Commit

Permalink
Merge 4eadcf2 into 078e316
Browse files Browse the repository at this point in the history
  • Loading branch information
JoviDeCroock committed Apr 8, 2019
2 parents 078e316 + 4eadcf2 commit 79906ac
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 8 deletions.
6 changes: 5 additions & 1 deletion hooks/src/index.js
Expand Up @@ -110,6 +110,7 @@ export function useEffect(callback, args) {
state._args = args;

currentComponent.__hooks._pendingEffects.push(state);
if (Array.isArray(options.effects)) options.effects.push(state);
afterPaint(currentComponent);
}
}
Expand All @@ -125,7 +126,7 @@ export function useLayoutEffect(callback, args) {
if (argsChanged(state._args, args)) {
state._value = callback;
state._args = args;

if (Array.isArray(options.effects)) options.effects.push(state);
currentComponent.__hooks._pendingLayoutEffects.push(state);
}
}
Expand Down Expand Up @@ -220,6 +221,9 @@ if (typeof window !== 'undefined') {
function handleEffects(effects) {
effects.forEach(invokeCleanup);
effects.forEach(invokeEffect);
if (options.effects) {
effects.forEach(hook => options.effects = options.effects.filter(h => h!==hook));
}
return [];
}

Expand Down
14 changes: 7 additions & 7 deletions test-utils/src/index.js
Expand Up @@ -11,23 +11,23 @@ export function setupRerender() {
}

export function act(cb) {
options.effects = [];
const previousRequestAnimationFrame = options.requestAnimationFrame;
const rerender = setupRerender();
let flush;
// Override requestAnimationFrame so we can flush pending hooks.
options.requestAnimationFrame = (fc) => flush = fc;
// Execute the callback we were passed.
cb();
// State COULD be built up flush it.
if (flush) {
flush();
}
rerender();
// If rerendering with new state has triggered effects
// flush them aswell since options.raf will have repopulated this.
if (flush) {
flush();
// State COULD be built up flush it.
while (options.effects.length > 0) {
flush();
rerender();
}
}
options.effects = undefined;
options.requestAnimationFrame = previousRequestAnimationFrame;
}

Expand Down
37 changes: 37 additions & 0 deletions test-utils/test/shared/act.test.js
Expand Up @@ -60,6 +60,43 @@ describe('act', () => {
expect(scratch.textContent).to.include('Count: 1');
});

it('should flush series of hooks', () => {
const spy = sinon.spy();
const spy2 = sinon.spy();
function StateContainer() {
const [count, setCount] = useState(0);
useEffect(() => {
spy();
if (count===1) {
setCount(() => 2);
}
}, [count]);
useEffect(() => {
if (count === 2) {
spy2();
setCount(() => 4);
return () => setCount(() => 3);
}
}, [count]);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(c => c + 1)} />
</div>
);
}
act(() => render(<StateContainer />, scratch));
expect(spy).to.be.calledOnce;
expect(scratch.textContent).to.include('Count: 0');
act(() => {
const button = scratch.querySelector('button');
button.click();
});
expect(spy.callCount).to.equal(5);
expect(spy2).to.be.calledOnce;
expect(scratch.textContent).to.include('Count: 3');
});

it('should drain the queue of hooks', () => {
const spy = sinon.spy();
function StateContainer() {
Expand Down

0 comments on commit 79906ac

Please sign in to comment.