Skip to content

Commit

Permalink
Phased dispatcher (#14701)
Browse files Browse the repository at this point in the history
* Move DEV-only function right above where it's used

I don't like looking at this top-level function #petty

* Use different dispatchers for functions & classes

Classes support readContext, but not any of the other dispatcher
methods. Function support all methods.

This is a more robust version of our previous strategy of checking
whether `currentlyRenderingFiber` is null.

As a next step, we can use a separate dispatcher for each phase of the
render cycle (mount versus update).

* Use separate dispatchers for mount and update

* Remove mount code from update path

Deletes mount-specific code from the update path, since it should be
unreachable. To continue supporting progressive enhancement (mounting
new hooks at the end of the list), we detect when there are no more
current hooks and switch back to the mount dispatcher. Progressive
enhancement isn't officially supported yet, so it will continue to warn.

* Factoring nits

* Fix Flow

Had to cheat more than I would like

* More Flow nits

* Switch back to using a special dispatcher for nested hooks in DEV

In order for this strategy to work, I had to revert progressive
enhancement support (appending hooks to the end). It was previously a
warning but now it results in an error. We'll reconsider later.

* Always pass args to updateState and updateReducer

Even though the extra args are only used on mount, to ensure
type consistency.
  • Loading branch information
acdlite authored Jan 30, 2019
1 parent 9d483dc commit cb1ff43
Show file tree
Hide file tree
Showing 10 changed files with 1,001 additions and 557 deletions.
2 changes: 1 addition & 1 deletion packages/react-debug-tools/src/ReactDebugHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import type {ReactContext, ReactProviderType} from 'shared/ReactTypes';
import type {Fiber} from 'react-reconciler/src/ReactFiber';
import type {Hook} from 'react-reconciler/src/ReactFiberHooks';
import typeof {Dispatcher as DispatcherType} from 'react-reconciler/src/ReactFiberDispatcher';
import type {Dispatcher as DispatcherType} from 'react-reconciler/src/ReactFiberHooks';

import ErrorStackParser from 'error-stack-parser';
import ReactSharedInternals from 'shared/ReactSharedInternals';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -432,21 +432,25 @@ describe('ReactDOMServerHooks', () => {
expect(domNode.textContent).toEqual('hi');
});

itRenders('with a warning for useRef inside useReducer', async render => {
function App() {
const [value, dispatch] = useReducer((state, action) => {
useRef(0);
return state + 1;
}, 0);
if (value === 0) {
dispatch();
itThrowsWhenRendering(
'with a warning for useRef inside useReducer',
async render => {
function App() {
const [value, dispatch] = useReducer((state, action) => {
useRef(0);
return state + 1;
}, 0);
if (value === 0) {
dispatch();
}
return value;
}
return value;
}

const domNode = await render(<App />, 1);
expect(domNode.textContent).toEqual('1');
});
const domNode = await render(<App />, 1);
expect(domNode.textContent).toEqual('1');
},
'Rendered more hooks than during the previous render',
);

itRenders('with a warning for useRef inside useState', async render => {
function App() {
Expand Down
5 changes: 4 additions & 1 deletion packages/react-dom/src/server/ReactPartialRendererHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @flow
*/

import typeof {Dispatcher as DispatcherType} from 'react-reconciler/src/ReactFiberDispatcher';
import type {Dispatcher as DispatcherType} from 'react-reconciler/src/ReactFiberHooks';
import type {ThreadID} from './ReactThreadIDAllocator';
import type {ReactContext} from 'shared/ReactTypes';

Expand Down Expand Up @@ -113,6 +113,9 @@ function areHookInputsEqual(
}

function createHook(): Hook {
if (numberOfReRenders > 0) {
invariant(false, 'Rendered more hooks than during the previous render');
}
return {
memoizedState: null,
queue: null,
Expand Down
36 changes: 0 additions & 36 deletions packages/react-reconciler/src/ReactFiberDispatcher.js

This file was deleted.

Loading

0 comments on commit cb1ff43

Please sign in to comment.