在ReactJS中,使用数组索引作为键据说效果不佳,但我可以';你不能让它工作得不好吗?

在ReactJS中,使用数组索引作为键据说效果不佳,但我可以';你不能让它工作得不好吗?,reactjs,react-state,react-key-index,Reactjs,React State,React Key Index,如果我使用索引作为键,我不能使它不能很好地工作。唯一的方法是我对数组进行变异并使用index作为键。但是由于文档中说不要改变状态(数组),所以如果是这样的话,我不能让它工作得不好,这与文档中所说的相反。我如何证明它可能会断裂 函数应用程序(){ const[arr,setArr]=React.useState([“A”,“B”,“C”); 函数toggleSortOrder(){ 设newArr=[…arr]; newArr.reverse(); log(JSON.stringify(newA

如果我使用索引作为键,我不能使它不能很好地工作。唯一的方法是我对数组进行变异并使用index作为键。但是由于文档中说不要改变状态(数组),所以如果是这样的话,我不能让它工作得不好,这与文档中所说的相反。我如何证明它可能会断裂

函数应用程序(){
const[arr,setArr]=React.useState([“A”,“B”,“C”);
函数toggleSortOrder(){
设newArr=[…arr];
newArr.reverse();
log(JSON.stringify(newArr));
setArr(newArr);
}
返回(
    {arr.map((e,i)=>
  • {e}
  • )}
切换排序顺序 ) } ReactDOM.render(,document.querySelector(“#root”)
实际情况是,使用
映射
功能的索引将起作用,不建议使用,因为它是:

如果数组通过添加或删除元素或修改数组中的元素数进行更改,React将假定DOM元素与之前表示的组件相同。这意味着使用索引的影响可能是不可预测的,例如包含相同id的两个数组项

因此,建议:

  • 如果数组元素包含唯一id,或者可以基于结构形成唯一id,请执行此操作

  • 使用全局索引(如计数器)帮助创建动态ID。。。例如:

arr.map(元素=>{
计数器++;
返回(
  • {elem}
  • ); ); });

    这样可以确保
    具有唯一标识符。

    实际情况是,使用
    映射
    功能的索引将起作用,因此不建议使用该功能,因为它是:

    如果数组通过添加或删除元素或修改数组中的元素数进行更改,React将假定DOM元素与之前表示的组件相同。这意味着使用索引的影响可能是不可预测的,例如包含相同id的两个数组项

    因此,建议:

    • 如果数组元素包含唯一id,或者可以基于结构形成唯一id,请执行此操作

    • 使用全局索引(如计数器)帮助创建动态ID。。。例如:

    arr.map(元素=>{
    计数器++;
    返回(
    
  • {elem}
  • ); ); });

    这样可以确保
    键具有唯一标识符。

    键主要与性能有关。告诉react哪个旧组件对应于哪个新组件,这反过来帮助它快速确定更新dom所需的最小更改集。看

    因此,代码“中断”的意思是react认为需要编辑每个
  • 中的文本,而可以重新排列它们。您不会真正注意到您的玩具示例存在任何性能问题,但您可以构建其他更重要的示例。在这里,我渲染20000行,并将一行移到末尾。性能一点也不好,但如果正确使用键而不是基于索引,性能会更好

    const exampleData=[];
    for(设i=0;i<20000;i++){
    示例数据[i]={
    关键:我,,
    名称:“元素”+i,
    }
    }
    函数App(){
    const[useKeysWell,setUseKeysWell]=React.useState(false);
    const[data,setData]=React.useState(exampleData);
    函数move(){
    设置数据(上一个=>{
    让newData=[…prev.slice(1),prev[0]];
    返回新数据;
    });
    }
    const before=Date.now();
    设置超时(()=>{
    console.log('对账和提交',Date.now()-在'ms(大约)'之前);
    }, 0)
    返回(
    移动一个
    setUseKeysWell(prev=>!prev)}>使用键{useKeysWell?“更差”:“更好”}
    
      {data.map((e,i)=>
    • {e.name}
    • )}
    ) } ReactDOM.render(,document.querySelector(“#root”)
    关键主要是性能。告诉react哪个旧组件对应于哪个新组件,这反过来帮助它快速确定更新dom所需的最小更改集。看

    因此,代码“中断”的意思是react认为需要编辑每个
  • 中的文本,而可以重新排列它们。您不会真正注意到您的玩具示例存在任何性能问题,但您可以构建其他更重要的示例。在这里,我渲染20000行,并将一行移到末尾。性能一点也不好,但如果正确使用键而不是基于索引,性能会更好

    const exampleData=[];
    for(设i=0;i<20000;i++){
    示例数据[i]={
    关键:我,,
    名称:“元素”+i,
    }
    }
    函数App(){
    const[useKeysWell,setUseKeysWell]=React.useState(false);
    const[data,setData]=React.useState(exampleData);
    函数move(){
    设置数据(上一个=>{
    让newData=[…prev.slice(1),prev[0]];
    返回新数据;
    });
    }
    const before=Date.now();
    设置超时(()=>{
    console.log('对账和提交',Date.now()-在'ms(大约)'之前);
    }, 0)
    返回(
    移动一个
    setUseKeysWell(prev=>!prev)}>使用键{useKeysWell?“更差”:“更好”}
    
      {data.map((e,i)=>
    • {e.name}
    • )}
    ) } ReactDOM.render(,document.querySelector(“#root”)
    
    
    正确,上面的示例是基于性能的,当应用于非常大的表时,性能并不重要。对于这个简单的示例,是的,它是有效的。但如果您的子组件具有依赖于组件安装的状态或代码
    arr.map(elem => {
        counter++;
        return (
            <li key={elem + counter}>{ elem }</li>);
        );
    });