如果你是React的新手,你很可能想知道如何用React的JSX语法显示一个项目的列表。这个关于React中的列表组件的教程给了你一个逐步的演练,告诉你如何渲染一个简单的基元列表,如何渲染一个复杂的对象列表,以及如何在React中更新列表的状态。
如何在React中显示一个项目的列表?
下面的函数组件展示了如何渲染一个项目列表(JS原语)。对于数字列表而不是字符串,它的效果也是一样的。由于我们可以通过使用大括号在JSX中使用JavaScript,我们可以使用内置的JavaScript数组映射方法来迭代我们的列表项;并将它们从JavaScript原语映射到HTML元素。每个元素都收到一个强制性的关键道具。
const SimpleList = () => (
<ul>
{['a', 'b', 'c'].map(function(item) {
return <li key={item}>{item}</li>;
})}
</ul>
);
我们没有定义列表,而只是内联了它。在将列表声明为变量的情况下,它看起来就像下面这样。
const list = ['a', 'b', 'c'];
const SimpleList = () => (
<ul>
{list.map(function(item) {
return <li key={item}>{item}</li>;
})}
</ul>
);
我们还可以使用JavaScript箭头函数,使地图的内联函数更加轻量级。
const list = ['a', 'b', 'c'];
const SimpleList = () => (
<ul>
{list.map(item => {
return <li key={item}>{item}</li>;
})}
</ul>
);
由于我们在函数的块体中没有做任何事情,我们也可以把它重构为一个简洁的主体,省略返回语句和函数主体的大括号。
const list = ['a', 'b', 'c'];
const SimpleList = () => (
<ul>
{list.map(item => (
<li key={item}>{item}</li>
))}
</ul>
);
如果我们要在另一个组件中使用列表作为子组件,我们可以把列表作为道具传递给它。
const mylist = ['a', 'b', 'c'];
const App = () => (
<SimpleList list={mylist} />
);
const SimpleList = ({ list }) => (
<ul>
{list.map(item => (
<li key={item}>{item}</li>
))}
</ul>
);
这就是React的一个简单的列表组件例子。我们只有一个JavaScript基元的列表,如字符串或整数,对它进行映射,并为我们数组中的每个项目渲染一个HTML listitem。
如何在React中显示一个对象的列表?
对于JavaScript数组中的复杂对象来说,它的工作方式并没有什么不同。你再次用map方法遍历列表,为每个列表项输出你的HTML元素。只有在map函数中给出的值参数是一个对象,而不再是原始的。因此,你可以在你的JSX中访问该对象以输出它的不同属性。
import React from 'react';
const list = [
{
id: 'a',
firstname: 'Robin',
lastname: 'Wieruch',
year: 1988,
},
{
id: 'b',
firstname: 'Dave',
lastname: 'Davidds',
year: 1990,
},
];
const ComplexList = () => (
<ul>
{list.map(item => (
<li key={item.id}>
<div>{item.id}</div>
<div>{item.firstname}</div>
<div>{item.lastname}</div>
<div>{item.year}</div>
</li>
))}
</ul>
);
export default ComplexList;
这里的实现并没有什么不同。我们把一个对象的列表映射成一个HTML元素的列表。如果你想要一个列表表而不是一个子弹列表,你必须使用table、th、tr、td元素而不是ul、li列表元素。
如何在React中显示嵌套的列表?
如果你遇到二维的列表,你仍然可以使用之前的实现技术。首先,映射到你的第一个数组上,然后再映射到你的第二个数组内。为简化起见,我们在嵌套列表中使用两次相同的列表。
import React from 'react';
const list = [
{
id: 'a',
firstname: 'Robin',
lastname: 'Wieruch',
year: 1988,
},
{
id: 'b',
firstname: 'Dave',
lastname: 'Davidds',
year: 1990,
},
];
const nestedLists = [list, list];
const NestedList = () => (
<ul>
{nestedLists.map((nestedList, index) => (
<ul key={index}>
<h4>List {index + 1}</h4>
{nestedList.map(item => (
<li key={item.id}>
<div>{item.id}</div>
<div>{item.firstname}</div>
<div>{item.lastname}</div>
<div>{item.year}</div>
</li>
))}
</ul>
))}
</ul>
);
export default NestedList;
然而,将多个映射相互嵌套,很快就会成为应用程序可维护性的负担。这就是为什么从你的大列表组件中提取较小的组件(如NestedList、List、Item组件)是非常好的。
React 列表组件
为了保持你的React列表组件的整洁,你可以把它们提取为独立的组件,只关心它们的问题。例如,List组件确保映射到数组上,为每个项目渲染一个ListItem组件的列表,作为子组件。
const list = [
{
id: 'a',
firstname: 'Robin',
lastname: 'Wieruch',
year: 1988,
},
{
id: 'b',
firstname: 'Dave',
lastname: 'Davidds',
year: 1990,
},
];
const App = () => <List list={list} />;
const List = ({ list }) => (
<ul>
{list.map(item => (
<ListItem key={item.id} item={item} />
))}
</ul>
);
const ListItem = ({ item }) => (
<li>
<div>{item.id}</div>
<div>{item.firstname}</div>
<div>{item.lastname}</div>
<div>{item.year}</div>
</li>
);
列表组件向外部提供了一个API。这样,App组件就可以把数组作为列表道具传递给List组件。有条件渲染的一个小技巧。如果你不知道传入的列表是空的还是未定义的,就自己默认为一个空的列表。
const List = ({ list }) => (
<ul>
{(list || []).map(item => (
<ListItem key={item.id} item={item} />
))}
</ul>
);
List和ListItem组件在React应用程序中使用得非常频繁,以至于它们可以被当作列表模板或模板,因为你经常只是复制和粘贴简单列表的相同实现到你的代码中。因此,记住这个结构的列表组件并无大碍。
React 列表。更新项目
到目前为止,我们只看到了不被改变的列表项,因为它们只是被声明为一个变量或作为道具传递下来。但作为状态管理的列表呢?我们可以在列表中添加、更新和删除项目。在下面的所有例子中,我们将从相同的模板列表组件开始。
import React from 'react';
const initialList = [];
const List = () => {
const [list, setList] = React.useState(initialList);
return (
<div>
<ul>
{list.map(item => (
<li key={item}>{item}</li>
))}
</ul>
</div>
);
};
export default List;
让我们深入了解不同的例子,用React Hooks更新我们的列表项。以下所有的模式都是React中复杂状态管理的基础。
React 列表添加项目
下面的列表组件展示了一个有状态管理的列表,它可以通过一个受控的表单元素向列表中添加一个项目。
import React from 'react';
const initialList = [
'Learn React',
'Learn Firebase',
'Learn GraphQL',
];
const ListWithAddItem = () => {
const [value, setValue] = React.useState('');
const [list, setList] = React.useState(initialList);
const handleChange = event => {
setValue(event.target.value);
};
const handleSubmit = event => {
if (value) {
setList(list.concat(value));
}
setValue('');
event.preventDefault();
};
return (
<div>
<ul>
{list.map(item => (
<li key={item}>{item}</li>
))}
</ul>
<form onSubmit={handleSubmit}>
<input type="text" value={value} onChange={handleChange} />
<button type="submit">Add Item</button>
</form>
</div>
);
};
export default ListWithAddItem;
通过使用提交按钮来启动项目的创建,处理程序确保将该项目添加到有状态的列表中。同时,通过使用点击事件,防止了本地浏览器的行为;否则,浏览器会在提交事件后刷新。
React 列表。更新项目
下面的列表组件显示了一个有状态的管理列表,在这里可以用输入元素更新列表中的一个项目。
import React from 'react';
const initialList = [
{ id: 'a', name: 'Learn React', complete: false },
{ id: 'b', name: 'Learn Firebase', complete: false },
{ id: 'c', name: 'Learn GraphQL', complete: false },
];
const ListWithUpdateItem = () => {
const [list, setList] = React.useState(initialList);
const handleChangeCheckbox = id => {
setList(
list.map(item => {
if (item.id === id) {
return { ...item, complete: !item.complete };
} else {
return item;
}
})
);
};
return (
<ul>
{list.map(item => (
<li key={item.id}>
<label>
<input
type="checkbox"
checked={item.complete}
onChange={() => handleChangeCheckbox(item.id)}
/>
{item.name}
</label>
</li>
))}
</ul>
);
};
export default ListWithUpdateItem;
通过使用复选框元素来启动项目的更新,处理程序确保切换有状态列表中项目的布尔标志。
React 列表。删除项目
下面的列表组件显示了一个有状态的管理列表,它可以用一个按钮元素从列表中删除一个项目。
import React from 'react';
const initialList = [
{ id: 'a', name: 'Learn React' },
{ id: 'b', name: 'Learn Firebase' },
{ id: 'c', name: 'Learn GraphQL' },
];
const ListWithRemoveItem = () => {
const [list, setList] = React.useState(initialList);
const handleClick = id => {
setList(list.filter(item => item.id !== id));
};
return (
<ul>
{list.map(item => (
<li key={item.id}>
<label>{item.name}</label>
<button type="button" onClick={() => handleClick(item.id)}>
Remove
</button>
</li>
))}
</ul>
);
};
export default ListWithRemoveItem;
通过使用删除按钮来启动删除项目,处理程序确保从有状态列表中删除该项目。在使用函数设置状态时,React确保在删除后更新列表。
本教程的所有实现都可以在这个GitHub仓库中找到。这些是在React中处理列表的基本原理。为了跟进,这里有一些更多的(深入的)教程,教授更多详细的主题。