In preparing for the React interview, I summarized a lot of questions based on my actual experience and my previous source code analysis articles.
Previous source code analysis articles I have written are not read by many people, because in most cases you don’t need to go deep into the source code to understand the principles and solve practical problems, which is why I summarize these interview questions, so that you can get more revenue in a shorter time.
Since the discussion is from the perspective of interview questions, some points may not be very in-depth, I have posted relevant links under the questions, if you want to understand more, please click on these articles.
As there are many topics, divided into the first and second parts, this article will discuss the following 19 topics first:
-
What is the React lifecycle and what are the changes to the React lifecycle in version 16?
-
Is setState synchronous or asynchronous?
-
Why do setStates sometimes only work once in a row?
-
How does React implement its event mechanism?
-
Why does the React event bind this itself?
-
What is the difference between a native event and a React event?
-
What is the React composite event?
-
What is the sequence of React and native events? Can you mix them?
-
What is the virtual Dom?
-
Is the virtual Dom faster than the normal Dom?
-
In the virtual Dom? What does the Typeof property do?
-
What is the render flow of the React component?
-
Why does React have to be in your code?
-
Why must the React component start with a capital letter?
-
What performance optimizations did React make to render the real Dom?
-
What are higher-order components? How to do that?
-
What are the practical application scenarios of HOC in a business scenario?
-
What are the similarities and differences between HOC and mixins?
-
What are the advantages of Hook?
What is the React lifecycle and what are the changes to the React lifecycle in version 16?
15 Life Cycle
-
Initialization phase
-
Constructor constructor
-
GetDefaultProps Default value
-
GetInitialState State Default value
-
Mount the stage
-
Called before componentWillMount is initialized for rendering
-
Render component
-
ComponentDidMount is called after the component is mounted to the DOM
-
Update the stage
-
Call before componentWillReceiveProps components that will receive the new props
-
ShouldComponentUpdate Whether the component needs to be updated
-
ComponentWillUpdate called before the component is updated
-
Render component
-
ComponentDidUpdate is called after the component is updated
-
Unloading phase
-
ComponentWillUnmount called before the component is unmounted
16 Life Cycle
-
Initialization phase
-
Constructor constructor
-
GetDefaultProps Default value
-
GetInitialState State Default value
-
Mount the stage
-
staticgetDerivedStateFromProps(props,state)
-
render
-
componentDidMount
GetDerivedStateFromProps: Every time the component is rerender, including after the component is built (after the virtual DOM, before the actual DOM is mounted), and every time a new props or state is obtained; Each time a new props is received, an object is returned as the new state. Returning null means that no state needs to be updated. Cooperate with componentDidUpdate, can cover all usage of componentWillReceiveProps
-
Update the stage
-
staticgetDerivedStateFromProps(props,state)
-
shouldComponentUpdate
-
render
-
getSnapshotBeforeUpdate(prevProps,prevState)
-
componentDidUpdate
GetSnapshotBeforeUpdate: Trigger time: Update occurs after render and before component DOM rendering; Returns a value as the third argument to componentDidUpdate; With componentDidUpdate, you can override all usage of componentWillUpdate
-
Unloading phase
-
componentWillUnmount
-
Error handling
-
componentDidCatch
React16 deprecated componentWillMount, componentWillReceivePorps, new life cycle GetDerivedStateFromProps and getSnapshotBeforeUpdate have been added to componentWillUpdate to replace the deprecated hook functions.
React16 does not remove the three hook functions, but cannot be used with new hook functions. React17 will remove the three hook functions and add error handling (componentDidCatch).
Is setState synchronous or asynchronous?
-
Life cycle and composition events
In the React lifecycle and composition events, React is still in its update mechanism, and no matter how many times setState is called, the update will not be executed immediately. Instead, the pending update will be stored in _pendingStateQueue, The component to be updated is stored in the dirtyComponent.
When the last update mechanism completes, for example in the lifecycle, all components, i.e., the topmost component didmount, will set the batch flag to false. Components in dirtyComponent and state in _pendingStateQueue are pulled out and updated. This ensures that the component will not be re-rendered more than once.
componentDidMount() { this.setState({ index: this.state.index + 1 }) console.log('state', this.state.index); }Copy the code
Therefore, in the above code, when we immediately obtain the state after executing setState, we cannot obtain the updated state at this time, because in the React batch mechanism, the state is temporarily stored and will be updated uniformly after the batch mechanism is completed.
So. SetState itself is not asynchronous, but the React batch mechanism gives the illusion of asynchrony.
-
Asynchronous code and native events
componentDidMount() { setTimeout(() => { console.log('call setState); this.setState({ index: this.state.index + 1 }) console.log('state', this.state.index); }, 0); }Copy the code
In the code above, when we call setState in asynchronous code, according to the asynchronous mechanism of JavaScript, the asynchronous code will be temporarily stored and executed after all synchronous code is executed. At this time, the React batch mechanism has run out, and the processing flag is set to false. Then call setState to perform the update immediately and get the updated result.
Calling setState in a native event does not invoke the React batching mechanism, so the latest results are immediately available.
-
Best practices
The second argument to setState receives a function that will be called after the React batching mechanism is complete, so you want to get the updated value immediately after calling setState, in this callback function.
this.setState({ index: this.state.index + 1 }, () => { console.log(this.state.index); })Copy the code
Recommended reading: Explore the implementation mechanism of setState with practical problems
Why do setStates sometimes only work once in a row?
For example, the following code prints the same result:
componentDidMount() { this.setState({ index: this.state.index + 1 }, () => { console.log(this.state.index); }) this.setState({ index: this.state.index + 1 }, () => { console.log(this.state.index); })}Copy the code
React will combine setStates stored in the batch process with the _assign function, which is similar to Object’s assign function:
_assign(nextState, typeof partial === 'function' ? partial.call(inst, nextState, props, context) : partial);Copy the code
If the object is passed in, it will obviously be merged once, so the above code prints the same result both times:
Object.assign( nextState, {index: state.index+ 1}, {index: state.index+ 1})Copy the code
Assign (preState); assign (preState); assign (preState); assign (preState)
componentDidMount() { this.setState((state, props) => ({ index: state.index + 1 }), () => { console.log(this.state.index); }) this.setState((state, props) => ({ index: state.index + 1 }), () => { console.log(this.state.index); })}Copy the code
So the above code prints differently.
-
Best practices
React merges multiple consecutive set states, so if you want to immediately use the result of the last setState for the next setState, you can make the setState accept a function instead of an object. This function takes a state as the first argument and props as the second argument when the update was applied.
How does React implement its event mechanism?
React events are not bound to real Dom nodes, but are distributed uniformly on the outermost document via the event broker.
When a component is mounted or updated:
-
Check whether an event is added or deleted using lastProps and nextProps. Invoke the event registration and uninstallation methods, respectively.
-
The enqueuePutListener of EventPluginHub is called for event storage
-
Get the Document object.
-
Determine whether to bubble or capture based on the event name (such as onClick, onCaptureClick).
-
Check whether the addEventListener method exists, otherwise use attachEvent (compatible with IE).
-
Register native event callbacks to document as dispatchEvent(unified event distribution mechanism).
Event initialization:
-
The EventPluginHub manages the Callback for React synthesized events and stores the callback in listenerBank, along with the Plugin for synthesized events.
-
Gets a unique identifying key for the element to which the event is bound.
-
The callback is stored in listenerBank according to the event type, with a unique identifying key for the element.
-
The structure of listenerBank is listenerBank[registrationName][key].
When an event is triggered:
-
Trigger the callback dispatchEvent of the document register native event
-
Gets the element that triggers the deepest level of the event
-
Iterate through all the parent elements of this element, processing each element in turn.
-
Construct a composite event.
-
The synthesized events for each level are stored in the eventQueue eventQueue.
-
Traverse eventQueue.
-
Determine whether the current event executes a bubbling prevention method by isPropagationStopped.
-
If bubbling is prevented, stop traversal, otherwise the synthesized event is executed through executeDispatch.
-
Release the event that has been processed.
React overrides the stopPropagation method in its own composite event, set isPropagationStopped to true, and then determines whether to proceed with each level of events based on that loop. This is the bubble mechanism React implements itself.
React: The React event mechanism
Why does the React event bind this itself?
In the event processing flow mentioned above, React performs uniform event distribution on document, and dispatchEvent simulates event bubbling and capture by looping through all levels of events.
In the React source code, the invokeGuardedCallback method is called when specific event handlers are to be called.
function invokeGuardedCallback(name, func, a) { try { func(a); } catch (x) { if(caughtError === null) { caughtError = x; }}}Copy the code
As you can see, the event handler is called directly without specifying the component to call, so getting this directly without manual binding is not accurate, so we need to manually bind the current component to this.
What is the difference between a native event and a React event?
-
React events are named with a hump instead of all lowercase.
-
With JSX, you pass a function as an event handler, not a string.
-
In React you cannot prevent default behavior by returning false. PreventDefault must be explicitly called.
What is the React composite event?
React defines parameters for each event handler function, known as synthesized events, according to the W3C specification.
The event handler passes an instance of SyntheticEvent, which is a cross-browser native event wrapper. It has the same interface as browser native events, including stopPropagation() and preventDefault(), and they work the same in all browsers.
The React synthesized SyntheticEvents use event pooling, which saves a lot of memory without constantly creating and destroying event objects.
In addition, browsers create this event type as a composite event regardless of browser environment, thus achieving browser compatibility.
What is the sequence of React and native events? Can you mix them?
All React events are distributed uniformly through Document. React events are handled only after the actual Dom triggers the event and bubbles up to the Document.
So the native event executes first, then executes the React composite event, and finally executes the event that’s actually mounted on the Document
React events and native events should not be mixed. If the stopPropagation method is executed in the native event, other React events will become invalid. All React events will not be triggered because all element events will not be able to bubble to document.
What is the virtual Dom?
In a native JavaScript program, we create and change the DOM directly, and DOM elements communicate with our application through events we listen for.
React converts your code into a JavaScript object, which in turn converts it into the real DOM. This JavaScript object is called the virtual DOM.
When we need to create or update elements, React first makes the VitrualDom object create and change, and then renders the VitrualDom object into the real DOM.
When we need to listen for events on the DOM, we first listen for events on VitrualDom, which responds by proxying native DOM events.
An in-depth look at the rendering process and features of the virtual DOM
Is the virtual Dom faster than the normal Dom?
There are a lot of articles that say VitrualDom can improve performance, but the claim is really one-sided.
It goes without saying that manipulating the DOM directly is very performance-intensive. React uses VitrualDom to manipulate the DOM.
VitrualDom doesn’t have any advantage when rendering for the first time, even though it does more computation and consumes more memory.
VitrualDom’s advantage lies in React’s Diff algorithm and batch strategy. React calculates how to update and render the DOM in advance of page updates. In fact, we can judge and implement this calculation process by ourselves when we operate DOM directly, but it will definitely cost a lot of energy and time. Moreover, it is often not as good as React. So React helped us “boost performance” in the process.
So, I’m more inclined to say that VitrualDom helps us develop more efficiently by helping us calculate how to update more efficiently when repeating renderings, not that it’s faster than DOM manipulation.
In the virtual Dom? What does the Typeof property do?
There’s one in ReactElement, right? Typeof property, which is assigned REACT_ELEMENT_TYPE:
var REACT_ELEMENT_TYPE = (typeof Symbol === 'function' && Symbol.for && Symbol.for('react.element')) || 0xeac7;Copy the code
Visible,? Typeof is a variable of type Symbol, which prevents XSS.
This can be a problem if your server has a bug that allows the user to store arbitrary JSON objects and the client code requires a string:
// JSONlet expectedTextButGotJSON = { type: 'div', props: { dangerouslySetInnerHTML: { __html: '/* put your exploit here */',}}};letmessage = { text: expectedTextButGotJSON }; <p> {message.text}</p>Copy the code
A variable of type Symbol cannot be stored in JSON.
ReactElement. IsValidElement function is used to judge whether a React component is effective, here is the concrete implementation of it.
ReactElement.isValidElement = function (object) { return typeof object === 'object'&& object ! == null && object.$$typeof=== REACT_ELEMENT_TYPE; };Copy the code
React render will render the React render. Typeof identifiers and components that fail rule verification are filtered out.
When your environment does not support Symbol,? Typeof is assigned to 0xeAC7, and the React developers give the answer as to why:
0xeAC7 looks a bit like React.
What is the render flow of the React component?
-
Write React components using React. CreateElement or JSX. Virtually all JSX code will eventually be converted to React. CreateElement (…) Babel helps us through this transformation process.
-
The createElement function handles special props such as key and ref, assigns defaultProps to the defaultProps, and handles the passed child node to construct a ReactElement object (the so-called virtual DOM).
-
Reactdom.render renders the generated virtual DOM to the specified container, which uses batch processing, transaction mechanisms and browser-specific performance optimization, and finally converts to the real DOM.
Why does React have to be in your code?
JSX is just for react. createElement(Component,props,… Grammar sugar provided by the children) method.
All JSX code ends up being converted to react.createElement (…). Babel helps us through this transformation process.
So any code that uses JSX must incorporate React.
Why must the React component start with a capital letter?
When compiled, Babel determines the initial letter of a component in JSX. When the initial letter is lowercase, it is considered a native DOM tag. The first variable of createElement is compiled as a string. When the initial letter is uppercase, it is considered a custom component, and the first variable of createElement is compiled as an object.
What performance optimizations did React make to render the real Dom?
In Internet Explorer (8-11) and Edge browsers, it is much more efficient to insert nodes one by one without descendants than to insert an entire serialized node tree.
React uses lazyTree to render individual nodes in turn in IE (8-11) and Edge, whereas in other browsers the entire large DOM structure is first built and then inserted into the container as a whole.
Also, when rendering nodes individually, React takes into account special nodes such as fragments, which are not inserted one by one.
What are higher-order components? How to do that?
High-order components can be seen as an implementation of the React decorator pattern. High-order components are functions that take a component as an argument and return a new component.
HOC is an advanced technique in React that reuses component logic. But higher-order components themselves are not a Replay API. It’s just a pattern, and that pattern is necessarily generated by the combinatorial nature of React itself.
function visible(WrappedComponent) { return class extends Component { render() { const { visible, ... props } = this.props;if (visible === false) return null; return <WrappedComponent {...props} />; } }}Copy the code
The above code is a simple application of HOC. The function receives a component as an argument and returns a new component. The new component can receive a Visible props and determine whether to render visible according to the value of visible.
We can implement higher-order components in two ways:
The property broker
The function returns a component that we define ourselves, and then returns the component to wrap in render, so that we can proxy all the props we pass in and decide how to render it. In effect, the higher-order component generated this way is the parent of the original component. The above function visible is an implementation of a HOC attribute proxy.
function proxyHOC(WrappedComponent) { return class extends Component { render() { return <WrappedComponent {...this.props} />; } }}Copy the code
Enhancements to native components:
-
Operates on all incoming props
-
The life cycle of an operational component
-
Static methods for manipulable components
-
Get refs
Reverse inheritance
Return a component that inherits the original component and calls render in render. Because it inherits from the original component, it can access the lifecycle, props, state, render, and so on of the original component, and it can manipulate more properties than the property proxy.
function inheritHOC(WrappedComponent) { return class extends WrappedComponent { render() { returnsuper.render(); }}}Copy the code
Enhancements to native components:
-
Operates on all incoming props
-
The life cycle of an operational component
-
Static methods for manipulable components
-
Get refs
-
Operational state
-
Can render hijack
React Goes from Mixin to HOC to Hook
What are the practical application scenarios of HOC in a business scenario?
What HOC can do:
-
Combination of rendering
-
Conditions apply colours to a drawing
-
Operating props
-
Get refs
-
State management
-
The operating state
-
Rendering hijacked
Actual application scenarios of HOC in business:
-
Dot log
-
Access control
-
Two-way binding
-
Form validation
Concrete implementation please refer to my this article: https://juejin.cn/post/6844903815762673671
What are the similarities and differences between HOC and mixins?
Both Mixin and HOC can be used to solve the React code reuse problem.
Images from the Internet
-
Mixins can be interdependent and coupled to each other, which is not conducive to code maintenance
-
Methods in different mixins can conflict with each other
-
There are so many mixins that components can sense and even deal with them, which can snowball in code complexity
The emergence of HOC can solve these problems:
-
A higher-order component is a pure function with no side effects; the higher-order components do not depend on each other for coupling
-
Higher-order components can also cause conflicts, but we can avoid these behaviors by following conventions
-
Higher-order components don’t care how or why the data is used, and wrapped components don’t care where the data comes from. The addition of higher-order components does not burden the original components
What are the advantages of Hook?
-
Reduce the risk of state logic reuse
Hooks and mixins have some similarities in usage, but the logic and state introduced by mixins can overwrite each other, and multiple hooks do not affect each other, so we do not need to focus part of our efforts on preventing conflicts that avoid logic reuse. Using HOC without conforming to the convention can also lead to conflicts, such as props overrides, which can be avoided by using hooks.
-
Avoid hell of nesting
Heavy use of HOC makes our code very deeply nested, and with HOC we can achieve flat reuse of state logic without heavy component nesting.
-
Make components easier to understand
As we build our programs using class components, they each have their own state, and the complexity of business logic makes these components bigger and bigger, with more and more logic called in each lifecycle and harder to maintain. Using hooks allows you to extract more common logic and split a component into smaller functions rather than forcing a life-cycle approach to split.
-
Use functions instead of classes
Writing a class may require more knowledge than writing a function, with more points to watch out for, such as this pointing, binding events, and so on. In addition, computers can understand a class faster than they can understand a function. Hooks allow you to use more of React’s new features outside of classes.
The next preview:
-
What is the strategy of the Actdiff algorithm?
-
What does a Key do in React?
-
What is ReactFiber? Why should it be introduced?
-
Why is it recommended to make web requests in componentDidMount?
-
React code optimization?
-
What are the principles for designing the React component?
-
What is the core philosophy of Redux?
-
What is Redux middleware?
-
What is the implementation strategy for Reduxconnect?
-
What is the core philosophy of Mox?
-
What are the similarities and differences between Redux and Mobx?
Reprint