Contents
Introduction
Of the hooks for achieving side effects in React’s Functional Component, I investigated how the most obvious useState is achieved.
Find out
Check out React release
Clone React from github and check out the latest v17.0.1 tag at the time of writing
$ git clone [email protected]:facebook/react.git
$ cd react
$ git checkout v17.0.1
Find the part where useState is exported
When I opened it in VSCode and useState
searched frankly, I found that line 95 of React.js was exported, and its implementation was line 80 of ReactHooks.js.
Exploring the implementation earnestly
const dispatcher = ReactCurrentDispatcher.current
So ReactCurrentDispatcher.current
I need to find out what it is.ReactCurrentDispatcher
Implementation is ↓
const ReactCurrentDispatcher = {
/**
* @internal
* @type {ReactComponent}
*/
current: (null: null | Dispatcher),
};
export default ReactCurrentDispatcher;
Since this is all, ReactCurrentDispatcher.current =
I searched for the fact that there must be a part where the value is pushed into the current, and I found that 112 cases were caught in 7 files, and I was about to break my heart quickly.
However, maybe the value is set from various places, so it would be nice if I could get a static Dispatcher, so if Dispatcher
I investigated what I did not see, useState
the interface in it was there.
Then, if you check the implementation of Dispatcher, it seems that it will be enough, so check the implementation of Dispatcher.
I should have imported Dispatcher in the implementation part, so when type {Dispatcher
I searched for it, ReactPartialRendererHooks.js
was importing it, and it was useState
exporting the implementation of other hooks.
I did it.
Looking at the essential useState implementation, useReducer is used internally, so this time useReducer
read the implementation.
useState
Kara useReducer
reducer, which is passed to the, basicStateReducer
so the useState
teeth useReducer
how that is implemented as, special of.
useReducer
In isReRender
have the flag is referenced that, probably at the time of re-drawing wonder this flag is set.
If you read the implementation that is not redrawing, for the time being, it seems that the implementation of Dispatch is made in this, and when this is called, redrawing runs.
I don’t care about the redrawing mechanism because it is not the subject of this survey.
Next, when I read the implementation of redrawing, memoizedState
it seems that the value is cached in and the updated value and the already created Dispatch are returned.
That’s all Hooks itself is doing, and the rest is Dispatch
the part to run redrawing, so that’s it.
Check it out
At least useState
the useReducer
they did not do is a big deal in the only state management.
The big thing is probably the part to redraw with Dispatch.
I would like to investigate that part one by one.
When I used it, I declared it first, so I felt like the reference I made once was being reused, but every time it was drawn, a new reference was returned. That’s right.
There is so many singleton state management that it seems difficult to prevent bugs, but I’m sure there is a library there.
At the end
Looking at the internal implementation, it is interesting to notice something new.
I wouldn’t have done it if I didn’t participate in the Advent calendar, so I’m glad I participated.
Cover photo from daveceddia.com
Discussion about this post