According to the knowledge point written in the way of specialized subject front end survival before. React react react React React React React The following questions are frequently asked by reacter during the interview in the past two months. Other topics will be sorted out later. Not very complete, hope big guys supplement.
series
Webpack for high frequency topics in the second half of the year
React Key functions
- Key is used to reduce unnecessary diff algorithm comparisons.
- Key is the identity identification of a component and node. During rerender, key can be used to determine whether the component already exists and whether it needs to be updated, destroyed or created, which improves the operation of diff algorithm on nodes of the same level.
SetState is updated synchronously or asynchronously
- Asynchronously under synchronous code, asynchronously under asynchronous code. You can see here
If setState is fired multiple times, render will execute several times
- Look at the link in the question for the answer.
What does setState do after that
- SetState enqueueUpdate execution, and execute the React ReactDefaultBatchingStrategy own update strategy
- IsBatchingUpdates are checked variables, which default to false.
- IsBatchingUpdates if true will enable batch update mode and the current component will be pushed into the dirtyComponent and set to false after the transaction ends
- IsBatchingUpdates if false, execute the batchedUpdates method to update state instantly. Call the batchedUpdates method and activate the update policy. Transaction. perform is called to perform the updated transaction. Wrapper performs updates to components.
Update strategy
-
React update policy has been enabled (event triggered) : Perform =>setState => Obtain the internal instance => store the new state => Discover that the update policy transaction has been started => Insert the current internal instance into the dirty Component array => SetState End => Update policy transaction Perform end => Wrapper process component state update
-
React update policy is not enabled (asynchronously triggered) : SetState => Obtain the internal instance => Store the new state => Find the update policy transaction is not started => Start the update policy transaction (bound with wrapper) => Transaction Perform => Put the current internal instance into the dirty component array => Update policy transaction Perform completes => The update of the component state is handled by wrapper. => The setState execution is complete
Update transaction with two wrappers (FLUSH_BATCHED_UPDATES, RESET_BATCHED_UPDATES)
- RESET_BATCHED_UPDATES close isBatchingUpdates = false;
- FLUSH_BATCHED_UPDATES is responsible for executing all dirtyComponents of the loop.
The React Diff algorithm
The Diff algorithm is used to calculate the difference between two virtual DOM and is the most expensive part of React.
The traditional DIFF algorithm compares the differences through cyclic recursion, and the algorithm complexity is O(N3).
The React Diff algorithm uses three policies to reduce the algorithm complexity from O(N3) to O(n).
- The cross-node operations of DOM nodes on the WebUI are rare and can be ignored.
- Components that have the same class have a similar DOM structure. Having different classes of components generates different DOM structures.
- Child nodes at the same level can be distinguished by unique ids.
React Diff implements the following strategies:
- Diff compares trees hierarchically, comparing only nodes at the same level of the two trees. Moving nodes across hierarchies will result in node deletion, re-insertion, and failure to reuse.
- Diff class comparison of components, recursive diff child nodes of the same class, different direct destruction reconstruction. Diff processes child nodes at the same level, reusing them briefly by key. If two trees have nodes with the same key, only the nodes are moved.
tree diff
React optimizes the tree algorithm in a concise way, that is, trees are compared at different levels. Two trees compare nodes at the same level
When a node is found to no longer exist, the node and its children are removed completely and are not used for further comparison
When nodes move across hierarchies, create new ones and delete old ones instead of moving them.
component diff
- If it is a component of the same type, continue to compare the Virtual DOM tree using the same policy
- If not, the component is judged to be a dirty Component and all child nodes under the entire component are replaced
Knowing that it is possible for components of the same type to have no change in their Virtual DOM can save a lot of diff time. Therefore, React allows the user to use shouldComponentUpdate() to determine if the component needs diff, but shouldComponentUpdate fails if the forceUpdate method is called.
element diff
When nodes are at the same level, diff provides three node operations: INSERT_MARKUP, MOVE_EXISTING, and REMOVE_NODE.
- INSERT_MARKUP: The new component type is not in the old collection; that is, the new node needs to be inserted.
- MOVE_EXISTING: old collection of new component types, and the element is updatable type, generateComponentChildren has been invoked
ReceiveComponent, in this case prevChild=nextChild, needs to be moved and can reuse the previous DOM node.
- REMOVE_NODE: the old component type is present in the new collection, but the corresponding element is different and cannot be reused or updated directly
Old components that are not in the new collection also need to be deleted.
What can be done to improve performance
Two basic points of front-end project optimization: 1. Reduce the number of connection requests as much as possible. 2. Minimize redrawing and reshooting as much as possible. React optimizations do the second step
-
Using pure components
-
SetState aspect merge execution
-
Scu render aspect, context effect
-
Lazily loaded component
-
List optimization
-
Use React Fragments to avoid extra markup
-
Do not use inline function definitions
-
Avoid asynchronous requests in componentWillMount()
-
Bind functions early in Constructor
-
The binding in the arrow function and constructor
When we add the arrow function, that function is added as an object instance, not as a stereotype property of the class. This means that if we reuse components multiple times, there will be multiple instances of these functions in every object created outside the component. This affects reusability.
-
Avoid using inline style attributes
-
Optimized conditional rendering in React
-
Do not export data in the Render method
-
Create error boundaries for components
Static getDerivedStateFromError() and componentDidCatch().
-
Immutable data structures for components
-
Iterate with unique keys
-
Event throttling and anti-shaking
-
Use the CDN
-
Use CSS animations instead of JavaScript animations
-
Enable gzip compression on the Web server
-
Use Web Workers to handle CPU-intensive tasks
-
Server-side rendering of the React component
React Status Management
-
Components use state internally for state management and need to minimize the complexity of state. And do setState only after merging in asynchronous code
-
Parent and child components pass data between them using props. In such scenarios, it is best to make child components into controlled components
-
Use context to pass data across hierarchical components.
Context has some issues to note. React has two context implementations: the old getChildContext and the new Provider and Customer modes. The previous version relied on the props pass route. If the mid-level component uses scU and returns false, the context cannot be passed to the target component. The new context does not have this problem. Because the Context is a global object, it is injected directly into the target component.
React Life cycle changes
- There are also two lifecycle methods for handling errors: Static getDerivedStateFromError() componentDidCatch()
- Cancel UNSAFE_componentWillMount
Data initialization (should be put in constructor) fetch does not get priority rendering because reconciliation and commit are synchronous operations and server rendering is problematic. In asynchronous mode fetch will be triggered multiple times and the data should be placed within the companyDidMount lifecycle subscribe event causes a memory leak server renders componentWillUnmount will not be called, async will be broken so componentWillUnmount will not be called
-
- Cancel UNSAFE_componentWillReceiveProps (preProps, preState), UNSAFE_componentWillUpdate (nextProps nextState) reasons:
Both life cycles are in reconciliation. In asynchronous mode, reconciliation is interrupted and can trigger multiple times. If fetch requests, props callbacks, and other side effects are done during the two life cycles, they can result in multiple executions
- The reason for adding static getDerivedStateFromProps(props, state) is
The component includes both controlled and uncontrolled states. The lifecycle usually refers to controlled states (state is determined by props), but if the component can set state itself, then the source of state can be props and the behavior of the component. React wants you to change your component to a controlled component; Use key method to reset the component; If you don’t want to re-render the component, you can also use the key as a props property to reset the process using the Derive State lifecycle
HOC aspect
Before the hook, hoc was a better tool
- The property broker
writing
Wrap Wrapped component
Function Hoc (Wrap){return class Box extends Component{render(){return <Wrap {... this.props}/> } } }Copy the code
Method of use
2. Class Detail extends Component{.... } export default Hoc(Detail)Copy the code
- To control the props
In hoc, this. Props can access props, which can be modified or added
- It can be accessed using refs
The concrete implementation is: Function refsHOC(WrappedComponent) {return class refsHOC extends React.Component { GetRef (wrappedComponentInstance) {/ / be able to get this component, so you can call the component method, the prop, the state of wrappedComponentInstance. HandleClick (); / / can rewrite the component state wrappedComponentInstance. SetState ({stateA: 'stateA' list: [{a: 1}]}) console.log(wrappedComponentInstance) } render() { const props = Object.assign({}, this.props, {ref: this.getRef.bind(this)}) return <WrappedComponent {... props}/> } } }Copy the code
- Abstract the state
To control the state, Hoc passes a callback in the form of props to change the props
- Wrap the wrappedComponent with other elements
This is easy to explain, usually for layout or style
- Reverse inheritance
writing
function MyContainer(WrappedComponent) {
return class MyComponent extends WrappedComponent {
render() {
return super.render()
}
}
}
Copy the code
In reverse inheritance, higher-order components can be asked about wrappedComponent via this call, meaning it has access to the state, props, component lifecycle methods, and Render methods. But it does not guarantee that the full tree of subcomponents will be parsed
- Rendering hijacked
You can control render before render, conditional rendering, etc.
export function MyContainer(WrappedComponent) {
return class MyComponent extends WrappedComponent {
render() {
return (
<div>
<h2>HOC Debugger Component</h2>
<p>Props</p> <pre>{JSON.stringify(this.props, null, 2)}</pre>
<p>State</p><pre>{JSON.stringify(this.state, null, 2)}</pre>
{super.render()}
</div>
)
}
}
}
Copy the code
- The operating state
Because this can access the wrap, you can manipulate stat.
React Event System
- React Event System
MVC, MVP, MVVM comparison
- Click here