[React Family Bucket] The key of the virtual DOM in React (diff algorithm) (accompanied by classic interview questions)

The classic interview questions

1. What is the function of the key of the virtual DOM in React? (What is the internal principle of key?)
2. Why is it better not to use index for key when traversing the list?

Second, the role of key in the virtual DOM

When the data in the state changes, React will generate a [new virtual DOM] based on the [new data], and then React uses the diff algorithm to compare the [new virtual DOM] and the [old virtual DOM]. The rules are as follows:
1. [Old virtual DOM] 找到了The same key as [New Virtual DOM] in DOM]:
    a. If the content of the virtual DOM 没变, directly use the previous real DOM
    b. If the content 变了of the virtual DOM, generate a new real DOM, and then replace the previous real DOM in the page
2. The same key in [Old Virtual DOM] as 未找到[New Virtual DOM]:
    create a new real DOM based on the data, and then render it to the page

3. Problems that may be caused by using index as the key

1. If the data is destroyed by adding in reverse order, deleting in reverse order, etc. , it will generate unnecessary real DOM updates ==> The page effect is no problem, but the efficiency is low.

2. If the DOM of the input class (input, etc.) is included in the structure, an incorrect DOM update will occur ==> There is a problem with the page

3. Attention! If there is no order-breaking operation such as adding and deleting data in reverse order, and it is only used to render the list, there is no problem using index as the key.

Code case 1: If index is used as the key, the requirement of adding in reverse order is realized - the page has no problem, but the efficiency is low

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>案例1-无输入类</title>
</head>

<body>
    <!-- 创建一个容器 -->
    <div id="test"></div>
    <!-- 引入react核心库 -->
    <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <!-- 引入react-dom,用于支持react操作dom -->
    <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <!-- 引入bable,将jsx转化为js -->
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
    <!-- 表示写的是jsx -->
    <script type="text/babel">
        // 1.创建类式组件
        class Demo extends React.Component {
      
      
            state = {
      
       person: [{
      
       id: 1, name: '小张' }, {
      
       id: 2, name: '小李' }] }
            add = () => {
      
      
                let {
      
       person } = this.state;
                let obj = {
      
      
                    id: 3,
                    name: '小王'
                }
                //逆序添加
                person.unshift(obj);
                this.setState({
      
       person: person });
            }
            //render放在类的原型对象上
            render() {
      
      
                const {
      
       person } = this.state;
                return (
                    <div>
                        <h1>案例1-无输入类</h1>
                        <button onClick={
      
      this.add}>逆序添加</button>
                        <ul>
                            {
      
      
                                person.map((item, index) => {
      
      
                                    return <li key={
      
      index}>{
      
      item.id}{
      
      item.name}</li>
                                })
                            }
                        </ul>
                    </div>
                )
            }
        }
        ReactDOM.render(<Demo id="id属性" />, document.querySelector('#test'));
    </script>
</body>

</html>

insert image description here

Code case 2: If index is used as the key, the need to add in reverse order to the structure containing the input class DOM - there is a problem with the page

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>案例2-有输入类</title>
</head>

<body>
    <!-- 创建一个容器 -->
    <div id="test"></div>
    <!-- 引入react核心库 -->
    <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <!-- 引入react-dom,用于支持react操作dom -->
    <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <!-- 引入bable,将jsx转化为js -->
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
    <!-- 表示写的是jsx -->
    <script type="text/babel">
        // 1.创建类式组件
        class Demo extends React.Component {
      
      
            state = {
      
       person: [{
      
       id: 1, name: '小张' }, {
      
       id: 2, name: '小李' }] }
            add = () => {
      
      
                let {
      
       person } = this.state;
                let obj = {
      
      
                    id: 3,
                    name: '小王'
                }
                //逆序添加
                person.unshift(obj);
                this.setState({
      
       person: person });
            }
            //render放在类的原型对象上
            render() {
      
      
                const {
      
       person } = this.state;
                return (
                    <div>
                        <h1>案例2-有输入类</h1>
                        <button onClick={
      
      this.add}>逆序添加</button>
                        <ul>
                            {
      
      
                                person.map((item, index) => {
      
      
                                    return <li key={
      
      index}>{
      
      item.id}{
      
      item.name} <input type="text"/></li>
                                })
                            }
                        </ul>
                    </div>
                )
            }
        }
        ReactDOM.render(<Demo id="id属性" />, document.querySelector('#test'));
    </script>
</body>

</html>

insert image description here
输入框发生错乱,所以这里key肯定是要使用唯一标识

Fourth, how to choose the key in the development

1、最好使用每条数据的唯一标识作为key,比如id、手机号、身份证、学号等

2、如果确定只是简单的展示数据,用index也是可以的。

The above is the content of the key in the virtual DOM in React . Please pay attention to the " React Family Bucket " column.
I will share the common problems in my usual projects and the knowledge of the written test and interview with you on CSDN, and make progress together. Come on.

Guess you like

Origin blog.csdn.net/weixin_46318413/article/details/122546587