1. Is setState asynchronous or synchronous?
- The synthetic event is asynchronous
- The hook function is asynchronous
- Native events are synchronous
- SetTimeout is synchronization
Related links: Do you really understand setState?
2, have a [email protected]+ life cycle
React Lifecycle My understanding of the React V16.4 lifecycle
UseEffect (FN, []) and componentDidMount
UseEffect captures props and state. So even in the callback function, you still get the original props and state. If you want the “most recent” value, you can use ref.
4. Why can’t hooks be put in conditional judgment?
Using setState as an example, inside React, hooks for each component (Fiber) are in the memoizeState property as a linked list:
In the Update phase, each time setState is called, the list executes next to move back one step. If setState is written in the condition judgment, assuming that the condition judgment is not valid and the setState method is not executed, all values of setState in the following will be offset, resulting in the occurrence of exceptions.
Bake React Hook thoroughly
5. What is Fiber?
React Fiber is a browser-based single-threaded scheduling algorithm.
React Fiber uses a mechanism similar to requestIdleCallback to do asynchronous diff. React implements a list-like data structure that changes the recursive diff to the traversal diff, making it asynchronously updatable.
Related Links: What is React Fiber?
6. Talk about diff algorithms
The time complexity of the traditional diff algorithm is O(n^3), which is unacceptable in front-end render. In order to reduce the time complexity, the React diff algorithm made some compromises, abandoning the optimal solution and eventually reducing the time complexity to O(n).
So what compromises does react Diff make? , please refer to the following:
1. Tree Diff: Only compare DOM nodes of the same layer, ignoring the movement of DOM nodes across different layers
React only compares DOM nodes in the same color box, that is, all child nodes under the same parent node. When a node is found to be nonexistent, the node and its children are completely removed and not used for further comparison.
This allows you to compare the entire DOM tree with only one walk through the tree.
This means that if a DOM node is moved across hierarchies, React will delete the old node and generate new ones without reuse.
Component diff: If the component is not of the same type, the old component is removed and a new component is created
3. Element diff: For a group of child nodes at the same level, unique ids are required to distinguish them
If there is no ID to differentiate, any insertion will cause the list after the insertion location to be completely re-rendered.
This is why you use unique keys when rendering lists.
7. What happens after setState is called?
- in
setState
React creates one for the current nodeupdateQueue
Update the queue. - And then it triggers
reconciliation
In this process, a scheduling algorithm named Fiber is used to start generating a new Fiber tree. The main feature of the Fiber algorithm is asynchronous and interruptible execution. - then
React Scheduler
The node with a higher priority is executed firstdoWork
Methods. - in
doWork
Method, React will execute it onceupdateQueue
To get a new node. Then compare the old and new nodes and Tag the old nodes with update, insert, replace, and so on. - The current node
doWork
When complete, it will be executedperformUnitOfWork
Method to obtain a new node, and then repeat the process. - When all the nodes are
doWork
When it’s done, it triggerscommitRoot
React enters the commit phase. - During the COMMIT phase, React updates the entire DOM element at once, based on the tags previously assigned to each node.
8. Why does virtual DOM improve performance?
The virtual DOM is equivalent to adding a cache between JS and the real DOM, using the DIff algorithm to avoid unnecessary DOM operations, thereby improving performance.
9. What is the wrong boundary? What does it do?
In React, if an error occurs in any one component, it will destroy the entire component tree, resulting in a blank page. At this point we can gracefully degrade these errors with error boundaries.
For example, the following encapsulated component:
class ErrorBoundary extends React.Component<IProps.IState> {
constructor(props: IProps) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError() {
// Update state so that the next rendering can display the degraded UI
return { hasError: true };
}
componentDidCatch(error, errorInfo) {
// Error logs can be reported to the server
console.log('Component crashes Error', error);
console.log('Component crash Info', errorInfo);
}
render() {
if (this.state.hasError) {
// You can customize the degraded UI and render it
return this.props.content;
}
return this.props.children; }}Copy the code
10. “Portals”?
Portal provides an excellent solution for rendering child nodes to DOM nodes that exist outside the parent component.
ReactDOM.createPortal(child, container)
Copy the code
What are the communication modes between React components?
The parent component communicates with the child component
1. Pass through props
The child component communicates with the parent component
1. Actively call the method passed by props and pass the desired information as parameters to the scope of the parent component
Cross level communication
1. Use the react Context to communicate. CreateContext creates the Context and useContext uses the Context.
Refer to the following code:
import React, { createContext, useContext } from 'react';
const themes = {
light: {
foreground: "# 000000".background: "#eeeeee"
},
dark: {
foreground: "#ffffff".background: "# 222222"}};const ThemeContext = createContext(themes.light);
function App() {
return (
<ThemeContext.Provider value={themes.dark}>
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
return (
<div>
<ThemedButton />
</div>
);
}
function ThemedButton() {
const theme = useContext(ThemeContext);
return (
<button style={{ background: theme.background.color: theme.foreground}} >
I am styled by theme context!
</button>
);
}
export default App;
Copy the code
2. Use state management libraries such as Redux or Mobx
3. Use a subscription publishing model
React Docs
12. How does the React parent invoke methods in its children?
If you are calling a child component from a method component (>= [email protected]), you can use useRef and useImperativeHandle:
const { forwardRef, useRef, useImperativeHandle } = React;
const Child = forwardRef((props, ref) = > {
useImperativeHandle(ref, () = > ({
getAlert() {
alert("getAlert from Child"); }}));return <h1>Hi</h1>;
});
const Parent = () = > {
const childRef = useRef();
return (
<div>
<Child ref={childRef} />
<button onClick={()= > childRef.current.getAlert()}>Click</button>
</div>
);
};
Copy the code
2. If you are calling a child component from a class component (>= [email protected]), you can use createRef:
const { Component } = React;
class Parent extends Component {
constructor(props) {
super(props);
this.child = React.createRef();
}
onClick = () = > {
this.child.current.getAlert();
};
render() {
return (
<div>
<Child ref={this.child} />
<button onClick={this.onClick}>Click</button>
</div>); }}class Child extends Component {
getAlert() {
alert('getAlert from Child');
}
render() {
return <h1>Hello</h1>; }}Copy the code
Call Child Method from parent
What does React do to optimize performance?
Optimization tools in class components
1. Use PureComponent PureComponent as base class.
2. Use the react. memo higher-order function to wrap components.
Use shouldComponentUpdate lifecycle function to customize the rendering logic.
Optimization in a method component
Use useMemo.
2. Use useCallBack.
The other way
1. When the list changes frequently, use a unique ID as the key instead of an array subscript.
Hide display components by changing CSS styles if necessary, rather than by conditional judgment.
Use Suspense and lazy for lazy loading, for example:
import React, { lazy, Suspense } from "react";
export default class CallingLazyComponents extends React.Component {
render() {
var ComponentToLazyLoad = null;
if (this.props.name == "Mayank") {
ComponentToLazyLoad = lazy(() = > import("./mayankComponent"));
} else if (this.props.name == "Anshul") {
ComponentToLazyLoad = lazy(() = > import("./anshulComponent"));
}
return (
<div>
<h1>This is the Base User: {this.state.name}</h1>
<Suspense fallback={<div>Loading...</div>} ><ComponentToLazyLoad />
</Suspense>
</div>)}}Copy the code
Suspense usage can be referred to the official documentation
Related: 21 React Performance Optimization Tips
Why does the React element have a $$typeof attribute?
The goal is to prevent XSS attacks. Because Synbol can’t be serialized, React can tell whether the current Element object is from the database or generated itself by having the $$Typeof attribute.
React refuses to process the element without the $$typeof attribute.
In older versions of React, an XSS attack would occur as follows:
// The server allows users to store JSON
let expectedTextButGotJSON = {
type: 'div'.props: {
dangerouslySetInnerHTML: {
__html: '/* Leave what you think */'}},// ...
};
let message = { text: expectedTextButGotJSON };
// React 0.13 has risks
<p>
{message.text}
</p>
Copy the code
Read about: Dan Abramov Blog
React how does React distinguish a Class component from a Function component?
General way is to use typeof and Function. The prototype. To judge whether the current class toString, as follows:
function isClass(func) {
return typeof func === 'function'
&& /^class\s/.test(Function.prototype.toString.call(func));
}
Copy the code
This approach has its limitations, however, because if you use a conversion tool such as Babel and change the class notation entirely to function, the above judgment will be invalid.
React distinguishes the Class component from the Function component in a clever way. Since all Class components inherit from React.component. react.component. react.component. react.component. react.component. react.component. react.component. react.component. react.component. react.component. react.component. react.component.function
AComponent.prototype instanceof React.Component
Copy the code
Read about: Dan Abramov Blog
16, What is the difference between React and HTML?
Event names must be lowercase in HTML:
<button onclick='activateLasers()'>
Copy the code
React uses the hump notation:
<button onClick={activateLasers}>
Copy the code
You can return false in HTML to prevent the default behavior:
<a href=The '#' onclick='console.log("The link was clicked."); return false; ' />
Copy the code
In React, preventDefault() must be explicitly called:
function handleClick(event) {
event.preventDefault()
console.log('The link was clicked.')}Copy the code
What are suspense components?
Suspense lets components “wait” for an asynchronous operation until it finishes rendering. In the following example, both components wait for the return value from the asynchronous API:
const resource = fetchProfileData();
function ProfilePage() {
return (
<Suspense fallback={<h1>Loading profile...</h1>} ><ProfileDetails />
<Suspense fallback={<h1>Loading posts...</h1>} ><ProfileTimeline />
</Suspense>
</Suspense>
);
}
function ProfileDetails() {
// Attempt to read user information, although the data may not have been loaded
const user = resource.user.read();
return <h1>{user.name}</h1>;
}
function ProfileTimeline() {
// Try to read the blog message, although the data may not be loaded
const posts = resource.posts.read();
return (
<ul>
{posts.map(post => (
<li key={post.id}>{post.text}</li>
))}
</ul>
);
}
Copy the code
Suspense can also be used for lazy loading, see the code below:
const OtherComponent = React.lazy(() = > import('./OtherComponent'));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>} ><OtherComponent />
</Suspense>
</div>
);
}
Copy the code
18. Why do component names in JSX start with a capital letter?
React needs to know whether a component or HTML element is being rendered.
19. What is redux?
Redux is a predictable state container designed for JavaScript applications.
It solves the following problems:
- Data transfer between components across hierarchies becomes easy
- All state changes need to be dispatched, making the entire data change traceable and troubleshooting easy.
But it also has disadvantages:
- It is not easy to understand many concepts
- Too much boilerplate code
20, React-redux implementation principle?
Redux is implemented using redux and react Context together with higher-order functions.
React.js little book
What’s the difference between Reudx and Mobx?
Thanks to Mobx Observable, precise updates can be achieved with Mobx. The corresponding Redux uses dispath to broadcast, and uses Provider and connect to compare and control the update granularity.
Related reading: Redux or MobX: An attempt to dissolve the Confusion
22. What does Redux asynchronous middleware do?
Suppose there is a requirement to load the Store dispatch with some information before requesting data. After the request completes, a loaded state is sent to Store Dispatch
Some students might do this:
function App() {
const onClick = () = > {
dispatch({ type: 'LOADING'.message: 'data is loading' })
fetch('dataurl').then(() = > {
dispatch({ type: 'LOADED'})}); }return (<div>
<button onClick={onClick}>click</button>
</div>);
}
Copy the code
But what if there’s a lot of use for this logic?
If you are smart enough, you can reuse the logic in onClick by abstracting it as follows:
function fetchData(message: string) {
return (dispatch) = > {
dispatch({ type: 'LOADING', message })
setTimeout(() = > {
dispatch({ type: 'LOADED'})},1000)}}function App() {
const onClick = () = > {
fetchData('data is loading')(dispatch)
}
return (<div>
<button onClick={onClick}>click</button>
</div>);
}
Copy the code
That’s fine, but fetchData(‘data is loading’)(dispatch) is a bit of an odd way to write it and adds to the developer’s mental load.
With the help of RudUx-related asynchronous middleware, using Rudux-chunk as an example, you can write it as follows:
function fetchData(message: string) {
return (dispatch) => {
dispatch({ type: 'LOADING', message })
setTimeout(() => {
dispatch({ type: 'LOADED' })
}, 1000)
}
}
function App() {
const onClick = () => {
- fetchData('data is loading')(dispatch)
+ dispatch(fetchData('data is loading'))
}
return (<div>
<button onClick={onClick}>click</button>
</div>);
}
Copy the code
It’s a little bit more cognitive, there’s no mystery to redux asynchronous middleware, and that’s basically what it does.
Why do we need Middleware for async flow in Redux?
23. What asynchronous middleware does Redux have?
1, the story – thunk
The source code is short and elegant, easy to use
2, the story – saga
Use THE JS generator to handle asynchrony, avoiding the problem of callbacks
3, the story – observables
It uses the idea of RxJS streams and their various powerful operators to deal with asynchronous problems
You can click on this if you likerepoWatch for more.