我有一个包含对象的数组。我正在创建此数组的映射,以使用span
组件呈现名称。
let data = [{"id": "01", "name": "Hi"}, {"id": "02", "name": "Hello"}];
我一直在使用以下两种不同的功能来迭代该对象数组,并使用map呈现JSX元素。
import React, { Component } from 'react';
class App extends Component {
render() {
let data = [{"id": "01", "name": "Hi"}, {"id": "02", "name": "Hello"}];
const items = data.map((key, i) => {
return <span key={key.id}>{key.name}</span>;
});
return (
<div>
{items}
</div>
);
}
}
export default App;
import React, { Component } from 'react';
class App extends Component {
render() {
let data = [{"id": "01", "name": "Hi"}, {"id": "02", "name": "Hello"}];
let rows = [];
data.map((key, i) => {
rows.push(<span key={key.id}>{key.name}</span>);
});
return (
<div>
{rows}
</div>
);
}
}
export default App;
我知道以上两种使用map
和呈现JSX元素的不同方式。除了这两种以外,还有其他方法可以做到吗?如果是这样,推荐哪个?
答案 0 :(得分:12)
我会这样做
const data = [{id: 1, name: 'a'}, {id: 2, name: 'b'}];
export default class App extends PureComponent {
render() {
return (
<div>
{data.map(({ id, name }) => <span key={id}>{name}</span>)}
</div>
);
}
}
现在,您的data
不会在每个渲染器上重新实例化,并且您不必浪费垃圾收集任何不必要的变量声明。
答案 1 :(得分:10)
通常,我遵循以下规则:
创建一个呈现项目的组件
// in some file
export const RenderItems = ({data}) => {
return data && data.map((d, i) => <span key={d.id}>{d.name}</span>) || null
}
钩住RenderItems
import { RenderItems } from 'some-file'
class App extends Component {
render() {
// you may also define data here instead of getting data from props
const { data } = this.props
return (
<div>
<RenderItems data={data} />
</div>
)
}
}
将数据附加到组件中
const data = [{"id": "01", "name": "Hi"}, {"id": "02", "name": "Hello"}]
<App data={data} />
即使您使用第二个示例代码,也遵循此规则不会影响性能。将项目推入数组并渲染项目。因为,您不是直接在渲染钩子内部工作。始终注意渲染钩子不会直接在其中实现任何逻辑。
此外,我不会仅仅为了使用密钥而创建id
:
const data = [{"name": "Hi"}, {"name": "Hello"}]
//... and when using index as key
.map((d, i) => <span key={'item-'+i}>
// or,
.map((d, i) => <span key={'item-'+i+'-'+d.name}>
请参见this post,为什么在使用索引作为键时为什么要遵循这种语法。
如果要避免使用不必要的html标签,可以使用React.Fragment
export const RenderItems = ({data}) => {
return data &&
data.map(
(d, i) => <React.Fragment key={d.id}>{d.name}</React.Fragment>
) || null
}
// and when rendering, you just return the component
return <RenderItems data={data} />
注意:
<></>
用作<React.Fragment></React.Fragment>
的别名。由于我们在其上使用键属性,因此不使用它。React.Fragment
的缩写。使用<></>
的示例:
<>{d.name}</>
这将以HTML形式呈现d.name
的值,而没有任何标签。当我们专门转换现有设计以响应应用程序时,这被认为是最好的。或者,可能还有其他情况。就像,我们将显示一个定义列表:
<dl>
<dt></dt>
<dd></dd>
<dt></dt>
<dd></dd>
<dt></dd>
</dl>
我们不想附加不必要的html标签,那么使用Fragment可以使我们的生活更轻松:
示例:
<>
<dt>{d.term}</dt>
<dd>{d.definition}</dd>
</>
最重要的情况是在td
(TR组件)中渲染tr
元素。如果我们不这样做,那我们就违反了HTML规则。该组件将无法正确渲染。反应时,会抛出错误。
此外,如果您有long list of props,如下所示:
const {
items,
id,
imdbID,
title,
poster,
getMovieInfo,
addToFavorites,
isOpen,
toggleModal,
closeModal,
modalData,
} = props
您可以考虑采用以下方式进行破坏:
const { items, ...other } = props
// and in your component you can use like:
<div modalData={other.modalData}>
但是,我个人更喜欢使用第一个示例代码。这是因为在开发时,我不需要每次都回顾其他组件或寻找控制台。在给定的示例中,有类似modalData={}
的键,因此我们可以轻松维护modalData={other.modalData}
。但是,如果需要像<div>{modalData}</div>
这样的代码怎么办?然后,您也可以同意我的偏好。
答案 2 :(得分:8)
第一种方法更好。
Array.prototype.map
在幕后创建一个数组,并在对每个元素应用修改后将其返回。 Functionality-1 创建两个数组,而 Functionality-2 创建三个数组。
功能1 读起来更好。这就是通常编写React代码的方式。对于这样的简单元素,我将为项目保存 const定义,并将map语句放入 JSX 中,以直接返回。
答案 3 :(得分:5)
通常,for
或while
语句是迭代数组的最有效方法。在非关键位置处理小型阵列的方式可以认为是微优化。
在React组件中习惯使用map
是因为它足够快并且可以将值作为表达式的一部分返回。
这是一种反模式:
let rows = [];
data.map((key, i) => {
rows.push(<span key={key.id}>{key.name}</span>);
});
map
应该将数组元素映射到其他值(因此命名),而不是迭代数组而不是forEach
或其他循环。可以使用ESLint array-callback-return
规则来跟踪此问题。
该组件是无状态的,不需要是Component
类。它可以是功能组件或PureComponent
类。由于data
是常量,因此不需要在每个渲染器上分配它:
const data = [{"id": "01", "name": "Hi"}, {"id": "02", "name": "Hello"}];
const App = props => <div>
{data.map(({ id, name }) => <span key={id}>{name}</span>)}
</div>;
答案 4 :(得分:2)
第一种方法是正确的。使用map函数遍历数组。
export default class App extends React.Component{
constructor(props){
super(props);
this.state = {
data: [{"id": "01", "name": "Hi"}, {"id": "02", "name": "Hello"}];
};
}
render(){
return(
<div>
{this.state.data.map((data,index)=>
<span key={data.id}>{data.name}</span>
)}
);
}
}
答案 5 :(得分:1)
您可以使用它来获得最佳理解
const data = [{id: 1, name: 'a'}, {id: 2, name: 'b'}];
export default class App extends React.Component {
render() {
return (
<div>
{data.map((data, dataIndex ) => <span key={dataIndex}>{data.name}</span>)}
</div>
);
}
}
在这里您可以了解到该名称属于with属性。
答案 6 :(得分:1)
函数toSpan
可以重复使用。
class App extends React.Component {
render() {
const data = [{id: `01`, name: `Hi`}, {id: `02`, name: `Hello`}]
const toSpan = ({id, name}) => <span key={id}>{name}</span>
return (
<div>{data.map(toSpan)}</div>
)
}
}