Skip to content

Commit

Permalink
Merge branch 'fix/effect_execution_order' of github.com:developit/pre…
Browse files Browse the repository at this point in the history
…act into fix/effect_execution_order
  • Loading branch information
JoviDeCroock committed Apr 2, 2019
2 parents 78e12f4 + 3b5fee7 commit 1bcec1a
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 5 deletions.
18 changes: 14 additions & 4 deletions debug/src/debug.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,18 +101,28 @@ export function initDebug() {
options.diffed = (vnode) => {
if (vnode._component && vnode._component.__hooks) {
let hooks = vnode._component.__hooks;
if (hooks._list.length > 0) {
hooks._list.forEach(hook => {
if (hook._callback && (!hook._args || !Array.isArray(hook._args))) {
console.warn(
`In ${vnode.type.name || vnode.type} you are calling useMemo/useCallback without passing arguments.\n` +
`This is a noop since it will not be able to memoize, it will execute it every render.`
);
}
});
}
if (hooks._pendingEffects.length > 0) {
hooks._pendingEffects.forEach((x) => {
if (!x._args || !Array.isArray(x._args)) {
hooks._pendingEffects.forEach((effect) => {
if (!effect._args || !Array.isArray(effect._args)) {
throw new Error('You should provide an array of arguments as the second argument to the "useEffect" hook.\n\n' +
'Not doing so will invoke this effect on every render.\n\n' +
'This effect can be found in the render of ' + (vnode.type.name || vnode.type) + '.');
}
});
}
if (hooks._pendingLayoutEffects.length > 0) {
hooks._pendingLayoutEffects.forEach((x) => {
if (!x._args || !Array.isArray(x._args)) {
hooks._pendingLayoutEffects.forEach((layoutEffect) => {
if (!layoutEffect._args || !Array.isArray(layoutEffect._args)) {
throw new Error('You should provide an array of arguments as the second argument to the "useEffect" hook.\n\n' +
'Not doing so will invoke this effect on every render.\n\n' +
'This effect can be found in the render of ' + (vnode.type.name || vnode.type) + '.');
Expand Down
17 changes: 16 additions & 1 deletion debug/test/browser/debug.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createElement as h, options, render, createRef, Component, Fragment } from 'preact';
import { useState, useEffect, useLayoutEffect } from 'preact/hooks';
import { useState, useEffect, useLayoutEffect, useMemo, useCallback } from 'preact/hooks';
import { setupScratch, teardown, clearOptions } from '../../../test/_util/helpers';
import { serializeVNode, initDebug } from '../../src/debug';
import * as PropTypes from 'prop-types';
Expand All @@ -9,13 +9,16 @@ import * as PropTypes from 'prop-types';
describe('debug', () => {
let scratch;
let errors = [];
let warnings = [];

let diffSpy;

beforeEach(() => {
errors = [];
warnings = [];
scratch = setupScratch();
sinon.stub(console, 'error').callsFake(e => errors.push(e));
sinon.stub(console, 'warn').callsFake(w => warnings.push(w));

clearOptions();
diffSpy = sinon.spy();
Expand All @@ -28,6 +31,7 @@ describe('debug', () => {

/** @type {*} */
(console.error).restore();
(console.warn).restore();
teardown(scratch);
});

Expand Down Expand Up @@ -120,6 +124,17 @@ describe('debug', () => {
expect(fn).to.throw(/createElement/);
});

it('should warn for useless useMemo calls', () => {
const App = () => {
const [people] = useState([40, 20, 60, 80]);
const retiredPeople = useMemo(() => people.filter(x => x >= 60));
const cb = useCallback(() => () => 'test');
return <p onClick={cb}>{retiredPeople.map(x => x)}</p>;
};
render(<App />, scratch);
expect(warnings.length).to.equal(2);
});

it('should print an error on invalid refs', () => {
let fn = () => render(<div ref="a" />, scratch);
expect(fn).to.throw(/createRef/);
Expand Down

0 comments on commit 1bcec1a

Please sign in to comment.