首页 > 解决方案 > React 如何更改具有关键属性的组件?

问题描述

我的根组件

import React, {Component} from 'react';
import Task from "./components/task";

class App extends Component {

    state = {
        keys: [0, 1]
    }

    changeKeysHandler = () => {
        const { keys } = this.state;
        const newKeys = keys.slice().reverse();
        this.setState({
            keys: newKeys
        })
    }

    render() {
        return (
            <div>
                <Task key={this.state.keys[0]}/>
                <Task key={this.state.keys[1]}/>
                <button onClick={this.changeKeysHandler}>Reverse</button>
            </div>
        )
    }
}

export default App;

我的任务组件

import React, {useState} from "react";

export default function Task() {
    const [ value, setValue ] = useState("Tofiq")
    return(
        <div>
            <input
                type="text"
                value={value}
                onChange={(event) => { setValue(event.target.value) }}
            />
        </div>
    )
}

当我更改键时,React Components 更改命令。但我不明白幕后发生了什么。React 如何与组件相关的关键属性。你能向我解释一下这个植入吗?

标签: reactjsreact-dom

解决方案


Akey是 React 唯一用来识别DOM元素的东西。

要了解 的工作key原理,让我们先了解 React 的行为key

假设我们有一个列表

<ul>
  <li>first</li>
  <li>second</li>
</ul>

默认情况下,当递归一个节点的子DOM节点时,React 只会同时遍历两个子节点列表,并在有差异时生成一个突变。

例如,当在子节点的末尾添加一个元素时,这两个树之间的转换效果很好:

<ul>
  <li>first</li>
  <li>second</li>
  <li>third</li>
</ul>

React将匹配两<li>first</li>棵树,匹配两<li>second</li>棵树,然后插入<li>third</li>树。

在 处插入元素beginning性能更差。例如,这两个树之间的转换效果不佳,React 会改变每个孩子,而不是意识到它可以保持<li>Duke</li><li>Villanova</li>子树的完整性。这种低效率可能是一个问题。

钥匙

为了解决这个问题,React 支持一个key属性。当孩子有 时keys,React 使用 将key原始树中的孩子与后续树中的孩子进行匹配。

例如,key在我们上面的低效示例中添加 a 可以使树转换高效:

<ul>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>

<ul>
  <li key="2014">Connecticut</li>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>

现在 React 知道带有 key 的元素'2014'是新元素,带有 key 和 的元素'2015''2016'刚刚移动的。

现在让我们谈谈你的问题

React 的keyprop 使您能够控制组件实例。每次 React 渲染你的组件时,它都会调用你的函数来检索它用来更新DOM. 如果您返回相同的元素类型,它会保留这些components/DOM节点,即使所有 * 道具都已更改。

在您的情况下,组件实例会根据它们的密钥进行更新和重用。在更改key列表时,诸如不受控制的输入之类的组件状态可能会以意想不到的方式混淆和更新。


推荐阅读