1, Virtual DOM and Diff algorithm of react
-
Virtual DOM and diff algorithm are two core concepts in React. We need to have a comprehensive understanding of them. This is very helpful for us to use scaffolding to develop projects, especially for projects in which the front and back ends of the enterprise are separated (similar to: background management system).
-
The internal execution process of virtual DOM is as follows:
- Using JavaScript object structure to represent the structure of DOM tree; Then use this tree to build a real DOM tree and insert it into the document;
- When the state changes, reconstruct a new object tree. Then compare the new tree with the old tree and record the difference between the two trees;
- Apply the differences recorded in step 2 to the real DOM tree built in step 1, and the view is updated.
- The principle analysis of virtual DOM is as follows:
- Virtual DOM essentially makes a cache between JS and DOM. It can be compared with CPU and hard disk. The reading speed of hard disk is relatively slow, so we will add a cache bar between them;
- On the contrary, since DOM runs slowly, we add a cache between JS and DOM. JS only operates the Virtual DOM, and writes the change result to the DOM at the last time.
- For diff algorithm, it is as follows:
- If the root element types of the two trees are different, React will destroy the old tree and create a new tree
- For React DOM elements of the same type, React will compare whether their attributes are the same and only update different attributes; When the DOM node is processed, React will recursively process the child nodes.
- Traverse the inserted element. If there is no key, React will change each child, delete and recreate it; To solve this problem, React provides a key attribute. When the child node has a key attribute, React will match the original tree and subsequent trees through the key.
-
For the execution process of diff algorithm, by binding the key, React will know that the element with the key '1024' is new, and only move the position for '1025' and '1026'.
-
Note the use of key as follows:
- The key attribute will only be used inside React and will not be passed to components
- When traversing data, it is recommended to use the key attribute in the component, < Li key = {obj. ID} > {obj. T}</li>
- A key only needs to be unique with its sibling nodes, not globally unique
- Reduce the array Index as the key as much as possible. When inserting elements into the array, the efficiency will be reduced
- The virtual DOM and Diff algorithm of react can be applied to the case of Jiugongge. The code is as follows:
<script type="text/babel"> class FlexView extends React.Component { constructor (props) { super(props) this.state = { shopArr: [] } } static defaultProps = { dataArr: [ { "icon": "f1", "name": "tomato" }, { "icon": "f2", "name": "Apple" }, { "icon": "f3", "name": "honey peach" }, { "icon": "f4", "name": "Banana" }, { "icon": "f5", "name": "Blueberry" }, { "icon": "f6", "name": "pineapple" }, { "icon": "f7", "name": "strawberry" }, { "icon": "f8", "name": "kiwifruit" }, { "icon": "f9", "name": "orange" } ] } render () { return ( <div className="box"> <div className="top"> <button onClick={() => this._addShop()}>Add</button> <button onClick={() => this._removeShop()}>Remove</button> </div> <div className="bottom"> {this.state.shopArr} </div> </div> ) } // Method of adding goods _addShop () { // Related variables const cols = 3, shopW = 100, shopH = 120, width = 320, height = 420 // Fetch data const { dataArr } = this.props // Remove subscript const index = this.state.shopArr.length if (index >= 9) { alert('I've bought a lot of fruit. I can't buy any more') return } // Find the rows and columns of the sub components const row = Math.floor(index / cols) const col = Math.floor(index % cols) // Find the left and top of the current box const xSpace = (width - cols * shopW) / (cols - 1) const ySpace = (height - 3 * shopW) / 2 const left = col * (shopW + xSpace) const top = row * (shopH + ySpace) // Create subcomponent load array const shopView = ( <div className="item" style={{left, top}} key={index}> <img src={'images/' + dataArr[index].icon + '.png'} style={{width: shopW * 0.8, height:shopW*0.8}} /> <span>{dataArr[index].name}</span> </div> ) // Update status const tempArr = this.state.shopArr tempArr.push(shopView) this.setState({ shopArr: tempArr }) } // Method of deleting goods _removeShop () { const tempArr = this.state.shopArr if (tempArr.length === 0) { alert('The shopping cart was empty') return } tempArr.pop() this.setState({ shopArr: tempArr }) } } // Rendering Components ReactDOM.render(<FlexView />, document.getElementById('app')) </script>