Javascript 在React map函数的前n个元素中动态添加一个类

Javascript 在React map函数的前n个元素中动态添加一个类,javascript,reactjs,jsx,map-function,Javascript,Reactjs,Jsx,Map Function,我正在通过一个数组进行映射,我希望为该数组的前n个元素分配一个类。前n个元素由父组件传递,并稳步增加 我可以使用类似于三元运算符的东西,比如className={index>=firstneelements?''MyClass';},但是这需要通过映射所有数组项。如果阵列中有数千个项目,且道具频繁更换,那么这似乎相当无效。有没有更快的方法完成这项任务?比如为索引小于第一个元素的所有元素构造while循环 import React from "react"; export c

我正在通过一个数组进行映射,我希望为该数组的前n个元素分配一个类。前n个元素由父组件传递,并稳步增加

我可以使用类似于三元运算符的东西,比如
className={index>=firstneelements?''MyClass';}
,但是这需要通过映射所有数组项。如果阵列中有数千个项目,且道具频繁更换,那么这似乎相当无效。有没有更快的方法完成这项任务?比如为索引小于第一个元素的所有元素构造while循环

import React from "react";

export const myComponent = ({ firstNElements, myArray }) => {
   return(
      <div>
         {myArray.map((arrayItem) => (
           <span key={arrayItem.key}>{arrayItem.content}</span>
         ))}
      </div>
   );
}
从“React”导入React;
export const myComponent=({firstneelements,myArray})=>{
返回(
{myArray.map((arrayItem)=>(
{arrayItem.content}
))}
);
}
我可以使用类似于三元运算符的东西,比如
className={index>=firstneelements?'''MyClass';}

这几乎就是您的操作方式(但是如果没有
,JSX表达式的内容就是一个表达式,而不是一个语句)

…但是,这需要通过映射所有数组项

您可以在渲染组件时执行此操作,无论您是否也在执行此操作。“几千”不太可能是
map
或创建跨距的问题(更可能是DOM渲染问题)

如果您的键是一致的,并且span的详细信息没有更改(它与上次的类相同,与上次的内容相同,等等),React将保留DOM中的等效
span
。在渲染后更新DOM时,如果它没有更改,则不会更新或替换它

您的组件看起来非常简单。因为它总是为相同的道具创建相同的输出,所以您可以使用它。从文件中:

如果您的函数组件在相同的道具下呈现相同的结果,您可以将其包装在调用React.memo中,以便在某些情况下通过记忆结果来提高性能。这意味着React将跳过渲染组件,并重用上次渲染的结果

注意,这里的“render”意味着调用组件函数来获取它的React元素,而不是DOM呈现

在其上使用
memo
如下所示:

export const myComponent = React.memo(({ firstNElements, myArray }) => {
   return(
      <div>
         {myArray.map((arrayItem) => (
           <span key={arrayItem.key}>{arrayItem.content}</span>
         ))}
      </div>
   );
});
。该类{
颜色:绿色;
}

对阵列进行切片 你可以把它切成两半,在上半场做你需要做的事。另外,使用slice不会改变原始数组值。突变可能非常糟糕,尤其是在react中。我回答了为什么

从“React”导入React;
export const myComponent=({firstneelements,myArray})=>{
让arrayFirstPart=yourArray.slice(0,第一个元素);
让arraySecondPart=yourray.slice(firstneelements,myArray.length);
返回(
{arrayFirstPart.map((arrayItem)=>(
{arrayItem.content}
))}
{arraySecondPart.map((arrayItem)=>(
{arrayItem.content}
))}
);
}

正如您在问题中明确提到的,方法是使用

className={index >= firstNElements ? '' : 'MyClass'}
但是,因为您已经在映射这些项,所以只需将第二个参数传递给map函数,该函数将作为索引,然后您可以将其与第一个元素进行比较,基本上如下所示

import React from "react";

export const myComponent = ({ firstNElements, myArray }) => {
   return(
      <div>
         {myArray.map((arrayItem, index) => (
           <span key={arrayItem.key} className={index >= firstNElements ? '' : 'MyClass'}>{arrayItem.content}</span>
         ))}
      </div>
   );
}
从“React”导入React;
export const myComponent=({firstneelements,myArray})=>{
返回(
{myArray.map((arrayItem,index)=>(
=第一个元素?“”:“MyClass”}>{arrayItem.content}
))}
);
}

React将根据道具中内容的变化来决定重新装载哪个dom元素,React就是这样做的。

您可以检查firstNArray元素的长度,而不是根据myArray的长度来映射myArray。我认为
切片
调用和创建它们构建的数组的开销不太可能小于重复条件表达式的开销。在以这种方式使代码复杂化之前,如果是我的项目,我需要确凿的证据证明这在我们的目标浏览器中更好。(不仅仅是因为一个人的直觉——包括我在内的任何人的直觉——很容易被证明是错误的。)@T.J.Crowder完全同意,我只需要映射它们,并在每次迭代中做一个if,就像你的答案所建议的,+1。但我希望他真的有一些很重的东西,也许他会去优化。但这些都是假设。顺便说一句,我真的很佩服你在这方面的工作,你的回答在很多场合都帮了我的忙。在这种情况下,三元运算符选项花费了大约15毫秒。我有100毫秒的间隔。所以这种方法花费的时间太长了。我试着把备忘录寄给你suggested@Tobi-但是,你确定你是在衡量有条件而非完整地图的成本吗?您是在测量第一次跑步还是后续跑步?(第一个通常是最慢的。)我在上面添加了一个快速、肮脏、相当幼稚的检查,建议使用5万件物品,条件成本为2-3毫秒。当然,即使组件对相同的输入产生相同的结果,您也希望避免这种情况(因此它是
React.memo
)的一个很好的候选者。问题实际上可能是由于将“MyClass”中前n个元素的宽度减少到零。这可能是我遇到的性能问题。下面的所有元素都会移位,但这是理想的效果。@Tobi-Ah,你说的是DOM渲染时间。无论您如何反应组件的
map
工作原理,这几乎都是一样的。它们是完全独立的,所以这里真的没有优化的方法吗?
import React from "react";

export const myComponent = ({ firstNElements, myArray }) => {
   return(
      <div>
         {myArray.map((arrayItem, index) => (
           <span key={arrayItem.key} className={index >= firstNElements ? '' : 'MyClass'}>{arrayItem.content}</span>
         ))}
      </div>
   );
}