使用 React 创建动态、可编辑表格
介绍
React.js 允许您构建复杂的表单,同时维护绑定到表单的对象的值。这种复杂性的一个例子是维护一个值数组,用户可以在单个界面中修改这些值。我们可以通过创建一个表来表达这一点,其中每行包含一个输入元素,该元素对应于我们要维护的对象数组中元素的值。
本指南将向您展示构建此类表单的不同方法以及它与 React.js 中的状态管理的关系。
设置
您将创建一个名为DynamicTable的组件,该组件维护两个状态属性:一条消息和一个名为items的消息数组。以下代码可帮助您入门:
import React from 'react';
export default class DynamicTable extends React.Component {
constructor(props) {
super(props);
this.state = {
message: "",
items: []
}
}
render() {
return (
<div>
<table>
<thead>
<tr>
<th>Item</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
);
}
}
请注意,该组件使用 HTML 表格的完整形式。如果在table中插入行时没有 tbody,React.js 会发出警告。
添加项目
创建一个简单的界面,让用户可以输入一条消息,并创建一个按钮来提交该消息。这个想法是,如果用户单击按钮,它将获取消息的值并将其添加到items数组中。当用户更改输入中的值时,消息状态将更新。UI 将位于表格下方,因此您的render()方法将如下所示:
render() {
return (
<div>
<table>
<thead>
<tr>
<th>Item</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<hr/>
<input type="text" />
<button>
Add Item
</button>
</div>
);
}
添加事件处理程序来更新消息:
updateMessage(event) {
this.setState({
message: event.target.value
});
}
将事件处理程序绑定到输入的onChange属性:
<input type="text" onChange={this.updateMessage.bind(this} />
接下来,创建按钮被点击时的事件处理程序:
handleClick() {
var items = this.state.items;
items.push(this.state.message);
this.setState({
items: items
});
}
该函数所做的就是获取当前项目数组和当前消息值,并在更新状态之前将它们推送到数组中。
将事件处理程序绑定到按钮的onClick属性:
<button onClick={this.handleClick.bind(this)}>
Add Item
</button>
要呈现表中的项目,请创建一个返回呈现的 JSX 的单独函数:
renderRows() {
var context = this;
return this.state.items.map(function(o, i) {
return (
<tr key={"item-" + i}>
<td>
<input
type="text"
value={o}
/>
</td>
<td>
<button>
Delete
</button>
</td>
</tr>
);
});
}
这里有两个重要的概念:
- 由于items是一个动态数组,预计会随时增长或缩小,因此将这些值映射到各个<tr>标记的函数应为其生成的每个节点维护一个key属性。React.js 要求其key的值在父元素(在本例中为<tbody> )内必须是唯一的。因此,使用值"item-" + i ,其中i是映射数组中元素的索引。
- 使用单独的上下文变量来引用它,因为在嵌套返回中,您需要引用DynamicTable组件的实例,以便稍后将事件处理程序绑定到输入和按钮。
在表主体中调用renderRows() ,如下所示:
<tbody>
{this.renderRows()}
</tbody>
修改项目
要修改每个表行输入中的项目中的每个元素,您必须创建一个事件处理程序,该处理程序知道应该更新数组中的哪个索引。创建一个如下所示的函数:
handleItemChanged(i, event) {
var items = this.state.items;
items[i] = event.target.value;
this.setState({
items: items
});
}
请注意,该函数的第一个参数是i,对应于数组的索引。第二个参数是event,它有一个属性target,指向手头的输入元素。然后,您可以通过分配event.target.value来更新items索引i处的元素。
将其挂接在表行的输入元素的onChange属性中:
<td>
<input
type="text"
value={o}
onChange={context.handleItemChanged.bind(context, i)}
/>
</td>
如代码所示,context用于调用handleItemChanged,因为它是对this的引用,而 this 是对组件本身的引用。接下来,context作为第一个参数绑定到bind()函数。context 之后的所有内容都将成为该函数的参数。在本例中,您传递i ,即映射函数给出的索引。
删除项目
您可以使用相同的技术通过为每个生成的按钮创建单个事件处理程序来删除项目:
handleItemDelete(i) {
var items = this.state.items;
items.splice(i, 1);
this.setState({
items: items
});
}
该方法接受索引i并将其用作splice(index, x)的参数,该方法从起始索引 index 处的数组中删除x个项目。在本例中,您只想删除1 个项目,即索引i处的项目本身。
将其也附加到按钮的onClick属性绑定索引i上:
<td>
<button
onClick={context.handleItemDelete.bind(context, i)}
>
Delete
</button>
</td>
总体代码
完整代码如下:
import React from 'react';
export default class DynamicTable extends React.Component {
constructor(props) {
super(props);
this.state = {
message: "",
items: []
}
}
updateMessage(event) {
this.setState({
message: event.<span cla
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~