React
React source code
Why does react use JSX?
Turnip greens, all have love.
But the react team thinks the templating scheme is bad:
- Templates separate the technology stack and add technology points.
- jsx that looks like html.
- React is too regular and needs jsx to assist
For example, using vue, the above is the html template, and the following is the js logic to form a component function. But react runs both html and execution logic in a class.
How does JSX map virtual DOM?
JSX is the syntactic sugar of creatElement, using babel's escaper, which is actually done by two methods, one is creatElement and the other is reactElement
// 定义一个 react 对象
reactElement(type, key, ref, self, source, ReactCurrentOwner.current, props)
Rreact Data Flow Management <br>Data Driven Views?
UI = render(data)
What is the difference between data and state?
State (state) and data (data), the communication in components is the communication of data, and the core of react is the management of data
Data flow:
- parent -> child
- child -> parent
- brother
- It doesn't matter
Unidirectional data flow
Disadvantages of MVC Bidirectional data flow. cause confusion.
Action -> Dispatcher -> Store -> View
|-------<------Action<-|
Messages sent by the ACTION view layer
redux is the state container for js
Action -> Reducer -> Store[state, state]
|-------<------View--<-|
Advantages and disadvantages of redux <br>Disadvantages:
- The usage process is complicated.
- The state will not be destroyed with the component, and the state will remain.
- When the store is updated frequently, it will be more laggy.
- ts are not supported.
mobx
The principle is to use es6 proxy data hijacking, and it will not be complicated to use redux.
React Fiber
Frames drop after 16ms.
The original React uses the execution stack of js to execute until the stack is empty. The new version of React maintains its own execution stack, traverses the tree structure in the form of a linked list, and optimizes the execution process.
Virtual DOM and diff algorithm
virtual DOM
An optimization method for React to render dom, the principle is to use createFragment, that is, "create fragments". All DOM operations will be performed in "fragments" until the operation is complete and then rendered together.
The diff algorithm <br>is a set of algorithms for React to update dom elements. Its core idea is to compare each node of the "node tree" and decide whether to update the node according to the result of the comparison. Through its optimization method, the time complexity of updating the tree is changed from O(n^3) to O(n).
diff strategy
- Ignore move operations across components
- Similar components create the same tree, and different classes create numbers of different classes (React Component and Function Component)
- bro, key
Divided into 3 update strategies tree diff, component diff, element diff:
tree diff: When the tree structure is updated, only the nodes at the same level are compared, and the starter nodes are only created and deleted. This means that if there is an intermediate node that moves a tree structure, the original tree will directly delete the node and its child nodes, and create the node and its child nodes in the new tree. In addition, the official does not recommend the existence of cross-node move operations.
Component diff: When a node is updated to a different type of node, it becomes a dirty component. React thinks that if it is updated to a different type of node, its structure must be different (tree structure), so directly delete the node and create it directly.
element diff: Calculate the direct move operation of sibling nodes, change from the original update strategy of deleting and re-creating the target node to identifying the key to determine whether it is the original node, and also obtain the basis for judging whether a move operation is generated.
From this, three optimization suggestions have been drawn:
- set key
- Don't update components to different types
- Reduce the need to move sibling components from the end to the head
Redux
To be added
React optimization
Common optimization details:
- function components instead of class components -> why? Reference 1 Reference 2
- HOC
- When using state management tools such as redux, some uncommon states do not need to be mounted in the model --> Why?
- First screen optimization scheme
- lazy lazy loading components
- The loading of react-router improves the experience
- ssr (service side rendering) and csr (client side rendering)
- pureComponent and shouldUpdate optimize update frequency
- componentDidCatch detects error boundaries
- Decrease label depth through Fragment
- Variable declarations in render functions are hoisted outside, reducing GC
React-Hooks
useState is equivalent to setState in class component.
function render() {
ReactDom.render(<App />, document.getElementById('root'))
}
function myState(initState) {
let state = initState
const update = (newState) => {
state = newState
render()
}
return [state, update]
}
function App () {}
useEffect is equivalent to several declaration cycle functions in class component
Why did 16.8 join Hook? Or why add function component?
- Reusing state from class components can be difficult. Although HOC is solved, it has the problem of nested hell.
- If the declaration cycle of class component changes, other life cycles may need to be changed.
- es6 class is not as friendly to beginners as function
- the pointer to this
Think from a designer's point of view.
SSR
next is mainly used in React.
npx create-next-app
react-router
A no-refresh router developed based on history.
There are three main types: hashHistory, borwerHistory, memoryHistory, commonly used are hashHistory and browserHistory.
The new version is react-router-dom,
import React from "react";
import { Router } from "react-router";
import { createBrowserHistory as createHistory } from "history";
import PropTypes from "prop-types";
import warning from "tiny-warning";
/**
* The public API for a <Router> that uses HTML5 history.
*/
class BrowserRouter extends React.Component {
history = createHistory(this.props);
render() {
return <Router history={this.history} children={this.props.children} />;
}
}
export default BrowserRouter;
Difference <br>Omitted
Difference between browerHistory and hashHistory
The hash route is refreshed according to the anchor point behind the change #, and the change is monitored through window.onhashChange, so as to find the corresponding file according to the route
History is implemented through the web API of html5's window.history
Features of hashHistory:
- Using history.location.hash ie history.location.hash = "abc" (equivalent to localhost/#abc)
- Refresh can only be achieved by modifying the address after #
- Monitor hash changes through window.onhashchange, window.addEventListener('onhashchange', hashchangeHandler)
- You can't think of window.history.go(-1) in this way, you can only change the url through a string
- Not friendly to search engines and difficult to track
Features of browerHistory:
- The History object is used, providing go, back, and forward methods
- The same url will be updated and pushed into the history
- Through the push and replace methods, the non-refresh jump is actually achieved through pushState and replaceState. Among them, pushState will be pushed into the browser history stack, that is, History.length + 1, but replaceState will not.
question
Use history to update the route and render it normally, and then refresh it, it will cause 404. (to be verified)
It is because the history has updated the url, that is, the access address. At this time, when requesting to the backend server, if there is no resource matching the address, it will be 404.
For example, nginx configures /test address access. Jump from /test to /say through the history router. When refreshing, the server will not find the resource, which can be avoided by configuring the parent path.
window.location also changes the url but causes a refresh
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。