Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to understand the implementation of Hooks in the Evolution of React Architecture

2025-03-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article introduces the relevant knowledge of "the evolution of React architecture how to understand the implementation of Hooks". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

How Hook is associated with components

As mentioned many times in previous articles, updateQueue and effectList under Fiber architecture are linked list data structures, and then mounted on the Fiber node. All the Hooks in a function component is also stored in the form of a linked list, and finally mounted to the fiber.memoizedState.

Function App () {const [num, updateNum] = useState (0) return updateNum (num = > num + 1)} > {num}} export default App

Let's take a brief look at the process of constructing a linked list when calling useState:

Var workInProgressHook = null var HooksDispatcherOnMount = {useState: function (initialState) {return mountState (initialState)}} function function mountState (initialState) {/ / New Hook node var hook = mountWorkInProgressHook () / / Cache initial value hook.memoizedState = initialState / / construct update queue Similar to fiber.updateQueue var queue = hook.queue = {pending: null, dispatch: null, lastRenderedState: initialState} / / for dispatching updates var dispatch = queue.dispatch = dispatchAction.bind (null, workInProgress, queue) / / [num, updateNum] = useState (0) return [hook.memoizedState, dispatch]} function mountWorkInProgressHook () {var hook = {memoizedState: null, baseState: null, baseQueue: null, queue: null Next: null} if (workInProgressHook = null) {/ / construct the chain header node workInProgress.memoizedState = workInProgressHook = hook} else {/ / if the linked list already exists After mounting to next workInProgressHook = workInProgressHook.next = hook} return workInProgressHook}

If there are two Hook at this time, the second Hook is mounted on the next attribute of the first Hook.

Function App () {const [num, updateNum] = useState (0) const [str, updateStr] = useState ('value:') return updateNum (num = > num + 1)} > {str} {num}} export default App

Hook

Update queue for Hook

Hook are connected to each other through .Next, and under each Hook object, there is a queue field, which, like updateQueue on the Fiber node, is an update queue. As mentioned in the last article, "Evolution of React Architecture-Update Mechanism", update queues in React Fiber architecture are stored through a linked list structure.

Class App extends React.Component {state = {val: 0} click () {for (let I = 0; I

< 3; i++) { this.setState({ val: this.state.val + 1 }) } } render() { return { this.click() }}>

Val: {this.state.val}

After clicking div, the generated setState is mounted on the fiber.updateQueue three times in the form of a linked list. When the MessageChannel receives the notification and performs the update operation, the update queue is taken out and the calculation result is updated to fiber.memoizedState.

SetState

The logic of hook.queue is exactly the same as that of fiber.updateQueue.

Function App () {const [num, updateNum] = useState (0) return {/ / 3 consecutive updates updateNum (num = > num + 1)}} > {num}} export default App; var dispatch = queue.dispatch = dispatchAction.bind (null, workInProgress, queue) / / [num, updateNum] = useState (0) return [hook.memoizedState, dispatch]

When useState is called, the second parameter of the returned array is dispatch, and dispatch is obtained after dispatchAction bind.

Function dispatchAction (fiber, queue, action) {var update = {next: null, action: action, / / omit scheduling-related parameters.}; var pending = queue.pending if (pending = null) {update.next = update} else {update.next = pending.next pending.next = update} queue.pending = update / / perform update scheduleUpdateOnFiber ()}

You can see that the linked list is constructed in the same way as fiber.updateQueue. We have updated num 3 times in a row through updateNum, and the final update queue is as follows:

Update queue

Update of function components

As shared in the previous article, the update process under Fiber architecture is divided into two steps: beginWork and completeWork. In beginWork, sub-components are constructed by render operation according to component type.

Function beginWork (current, workInProgress) {switch (workInProgress.tag) {/ / other types of component code omitted. Case FunctionComponent: {/ / the type here is the function of the function component / / for example, the previous App component Type is function App () {} var Component = workInProgress.type var resolvedProps = workInProgress.pendingProps / / component update return updateFunctionComponent (current, workInProgress, Component, resolvedProps)}} function updateFunctionComponent (current, workInProgress, Component, nextProps) {/ / Construction subcomponent var nextChildren = renderWithHooks (current, workInProgress, Component, nextProps) reconcileChildren (current, workInProgress, nextChildren) return workInProgress.child}

As you can see from the name, the renderWithHooks method is to construct a subcomponent with Hooks.

Function renderWithHooks (current, workInProgress, Component, props) {if (current! = = null & & current.memoizedState! = = null) {ReactCurrentDispatcher.current = HooksDispatcherOnUpdate} else {ReactCurrentDispatcher.current = HooksDispatcherOnMount} var children = Component (props) return children}

As you can see from the above code, when the function component is updated or rendered for the first time, the essence is to take out the function and execute it again. The difference is that ReactCurrentDispatcher is assigned different values, and the value of ReactCurrentDispatcher ultimately affects how useState invokes different methods.

According to the double caching mechanism mentioned in the previous article, current is an update operation when it exists, and it is rendered for the first time if it does not exist.

Function useState (initialState) {/ / first render point to HooksDispatcherOnMount / / update operation point to HooksDispatcherOnUpdate var dispatcher = ReactCurrentDispatcher.current return dispatcher.useState (initialState)}

The code for HooksDispatcherOnMount.useState has been introduced earlier, so I won't focus on it here.

/ / the code of HooksDispatcherOnMount has already introduced var HooksDispatcherOnMount = {useState: function (initialState) {return mountState (initialState)}}

Let's focus on the logic of HooksDispatcherOnMount.useState.

Var HooksDispatcherOnUpdateInDEV = {useState: function (initialState) {return updateState ()} function updateState () {/ / take out the current hook workInProgressHook = nextWorkInProgressHook nextWorkInProgressHook = workInProgressHook.next var hook = nextWorkInProgressHook var queue = queue.pending / / process update var first = pendingQueue.next var state = hook.memoizedState var update = first do {var action = update.action state = typeof action = = 'function'? Action (state): action update = update.next;} while (update! = = null & & update! = = first) hook.memoizedState = state var dispatch = queue.dispatch return [hook.memoizedState, dispatch]}

If you look at the previous setState code, the logic here is actually the same. Take out the action of the update object, execute it if it is a function, and replace the state directly if it is not a function.

This is the end of the content of "how to understand the implementation of Hooks in the evolution of React architecture". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report