举例说明React列表组件(附代码示例)

634 阅读6分钟

如果你是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中处理列表的基本原理。为了跟进,这里有一些更多的(深入的)教程,教授更多详细的主题。