React(3)-列表及简单表单

列表

使用{}在JSX构建一个元素集合。
使用JS的map()方法遍历数组,将数组中的元素变成<li>标签。

1
2
3
4
5
6
7
8
const number = [1,2,3,4,5];
const listitems = numbers.map((number) =>
<li>{number}</li>
);
ReactDOM.render(
<ul>{listItems}</ul>,
document.getElementById('root')
);

key

当创建元素时必须包含一个key属性。key属性帮助React识别元素的变化。

key的正确使用

一个元素的key最好是元素在列表中拥有的独一无二的字符串,万不得已时才使用索引作为key。

元素的key只有放在就近的数组上下文才有意义。故如果提取一个组件,就应把组件的key保留在该组件的元素上,而不是它里面的子元素上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function ListItem(props){
//子元素无需指定key
return <li>{props.value}</li>;
}
function NumberList(props){
const numbers = props.numbers;
const listItems = numbers.map((number) =>
//key应在数组的上下文中指定,经验法则:在map()中的元素需指定key属性
<ListItem key={number.toString()} value={number} />
);
return (
<ul>
{listItems}
</ul>
);
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById('root')
);

key的唯一性

key在兄弟节点之间必须唯一,但不是全局唯一。即当有两个不同的数组时,key可以相同。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const sidebar = (
<ul>
{props.posts.map((post) =>
<li key={post.id}>
{post.title}
</li>
)}
</ul>
);
const content = props.posts.map((post) =>
<div key={post.id}>
<h3>{post.title}</h3>
<p>{post.content}</p>
</div>
);

key传递信息给React,但不会传递给组件。因此,若需要使用key的值,需要使用其他属性将其显式的传递出来。

1
2
3
4
5
6
const content = posts.map((post) =>
<Post
key={post.id}
id={post.id}
title={post.title} />
);

在JSX中嵌入map()

以上都是声明单独的变量并将其包含在JSX中,但JSX允许在大括号{}中嵌入表达式,因此可以直接内联map()返回的结果。

1
2
3
4
5
6
7
8
9
10
11
12
function NumberList(props){
const numbers = props.numbers;
return (
<ul>
{numbers.map((number) =>
<ListItem key={number.toString()}
value={number}
/>
)}
</ul>
);
}

表单

HTML表单与其他DOM元素不同,它内部通常保持一些state,大多情况下,使用JavaScript函数可以方便的处理表单提交,同时访问用户填写的表单数据。实现此效果的标准方式是使用受控组件

受控组件

受控组件使React的state成为唯一数据源。渲染表单的React组件控制用户输入过程中发生的操作。(结合state及事件处理操作)

input

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class NameForm extends React.Component {
constructor(props) {
super(props);
//输入input组件值由state控制,此处设置初始值。
this.state = {value: ''};

this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
//input框内容改变事件
handleChange(event) {
this.setState({value: event.target.value});
}
//提交内容事件
handleSubmit(event) {
alert('提交的名字: ' + this.state.value);
event.preventDefault();
}

render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
名字:
//state.value是input框的唯一数据源
//onChange事件会在用户每一次按键后更新React的state
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="提交" />
</form>
);
}
}

textarea

text的使用与input相同,但默认有初值

select

select选择框的选中属性使用value控制,而不使用selected属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
constructor(props) {
super(props);
this.state = {value: 'coconut'};

this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}

render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
选择你喜欢的风味:
<select value={this.state.value} onChange={this.handleChange}>
<option value="grapefruit">葡萄柚</option>
<option value="lime">酸橙</option>
<option value="coconut">椰子</option>
<option value="mango">芒果</option>
</select>
</label>
<input type="submit" value="提交" />
</form>
);
}

option内容也可直接在select标签内将数组传递到vlue属性。使用多选时,设置multiple={true}

接受多个输入

当需要处理多个input元素时,给每个元素添加name属性,处理函数根据event.target.name选择要执行的操作。setState()自动将部分state合并到当前state。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
class Reservation extends React.Component {
constructor(props) {
super(props);
this.state = {
isGoing: true,
numberOfGuests: 2
};

this.handleInputChange = this.handleInputChange.bind(this);
}

handleInputChange(event) {
const target = event.target;
const value = target.name === 'isGoing' ? target.checked : target.value;
const name = target.name;

this.setState({
[name]: value
});
}

render() {
return (
<form>
<label>
参与:
<input
name="isGoing"
type="checkbox"
checked={this.state.isGoing}
onChange={this.handleInputChange} />
</label>
<br />
<label>
来宾人数:
<input
name="numberOfGuests"
type="number"
value={this.state.numberOfGuests}
onChange={this.handleInputChange} />
</label>
</form>
);
}
}
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2020-2024 Aweso Lynn
  • PV: UV: