Lists and Forms

Updated: 03 September 2023

Based on this EdX course

Lists

We can render a list of react elements using a few different methods

Loop

1
var elements = []
2
var array = [1,2,3,4,5]
3
4
for (let i = 0, i < array.length; i++){
5
elements.push(<li>{array[i]}</li>)
6
}
7
8
ReactDOM.render(
9
<ol>{elements}</ol>,
10
document.getElementById("root")
11
)

Map

1
var array = [
2
{ name: 'John', age: 5 },
3
{ name: 'Jeff', age: 6 },
4
{ name: 'Jenny', age: 7 },
5
]
6
7
var elements = array.map((el) => (
8
<li>
9
Name: {el.name}, Age: {el.age}
10
</li>
11
))
12
13
ReactDOM.render(<ol>{elements}</ol>, document.getElementById('root'))

Map in JSX

1
var array = [
2
{ name: 'John', age: 5 },
3
{ name: 'Jeff', age: 6 },
4
{ name: 'Jenny', age: 7 },
5
]
6
7
ReactDOM.render(
8
<ol>
9
{array.map((el) => (
10
<li>
11
Name: {el.name}, Age: {el.age}
12
</li>
13
))}
14
</ol>,
15
document.getElementById('root')
16
)

Using Keys

We can also use unique keys to render items quicker with the following

1
var array = [
2
{ id: 1, name: 'John', age: 5 },
3
{ id: 2, name: 'Jeff', age: 6 },
4
{ id: 3, name: 'Jenny', age: 7 },
5
]
6
7
ReactDOM.render(
8
<ol>
9
{array.map((el) => (
10
<li key={el.id}>
11
Name: {el.name}, Age: {el.age}
12
</li>
13
))}
14
</ol>,
15
document.getElementById('root')
16
)
1
var array = [
2
{ id: 1, name: 'John', age: 5 },
3
{ id: 2, name: 'Jeff', age: 6 },
4
{ id: 3, name: 'Jenny', age: 7 },
5
]
6
7
ReactDOM.render(
8
<ol>
9
{array.map((el, index) => (
10
<li key={index}>
11
Name: {el.name}, Age: {el.age}
12
</li>
13
))}
14
</ol>,
15
document.getElementById('root')
16
)

List Component

It can be useful to define a component that specifically renders lists as follows

1
class ListItem extends React.Component {
2
constructor(props) {
3
super(props)
4
}
5
6
render() {
7
return (
8
<li key={this.props.index}>
9
Name: {this.props.name}, Age: {this.props.age}
10
</li>
11
)
12
}
13
}
14
15
class List extends React.Component {
16
constructor(props) {
17
super(props)
18
}
19
20
render() {
21
return (
22
<ol>
23
{this.props.list.map((el, index) => (
24
<ListItem index={index} name={el.name} age={el.age} />
25
))}
26
</ol>
27
)
28
}
29
}
30
31
var array = [
32
{ id: 1, name: 'John', age: 5 },
33
{ id: 2, name: 'Jeff', age: 6 },
34
{ id: 3, name: 'Jenny', age: 7 },
35
]
36
37
ReactDOM.render(<List list={array} />, document.getElementById('root'))

Controlled Components

HTML form elements can be modified from the DOM as well as from the code, we use React to manage the state of these with what’s called Controlled Components

We tie the DOM state to the React state in order to more easily manage it

This is done with the following steps

  1. When an input value is changed, call an event handler to update the value
  2. Re-render the element with its new value

Input Fields

1
class ControlledText extends React.Component {
2
constructor(props) {
3
super(props)
4
this.state = { value: '' }
5
this.handleChange = this.handleChange.bind(this)
6
}
7
8
handleChange(event) {
9
this.setState({ value: event.target.value })
10
}
11
12
render() {
13
return (
14
<input
15
type="text"
16
value={this.state.value}
17
onChange={this.handleChange}
18
/>
19
)
20
}
21
}

Checkboxes

1
class ControlledCheckbox extends React.Component {
2
constructor(props) {
3
super(props)
4
this.state = { value: '' }
5
this.handleChange = this.handleChange.bind(this)
6
}
7
8
handleChange(event) {
9
this.setState({ value: event.target.checked })
10
}
11
12
render() {
13
;<input
14
type="checkbox"
15
checked={this.state.checked}
16
onChange={this.handleChange}
17
/>
18
}
19
}

Text Areas

1
class ControlledText extends React.Component {
2
constructor(props) {
3
super(props)
4
this.state = { value: '' }
5
this.handleChange = this.handleChange.bind(this)
6
}
7
8
handleChange(event) {
9
this.setState({ value: event.target.value })
10
}
11
12
render() {
13
return (
14
<textarea
15
type="text"
16
value={this.state.value}
17
onChange={this.handleChange}
18
/>
19
)
20
}
21
}

Selects

1
class ControlledSelect extends React.Component {
2
constructor(props) {
3
super(props)
4
this.state = { value: 0 }
5
}
6
7
handleChange(event) {
8
this.setState({ value: even.target.value })
9
}
10
11
render() {
12
return (
13
<select value={this.state.value} onChange={this.handleChange}>
14
<option value="0">Please select an option</option>
15
<option value="1">One</option>
16
<option value="2">Two</option>
17
<option value="3">Three</option>
18
</select>
19
)
20
}
21
}

Selects can also be dynamically generated as follows

1
class ControlledSelect extends React.Component {
2
constructor(props) {
3
super(props)
4
this.state = { value: 0 }
5
}
6
7
handleChange(event) {
8
this.setState({ value: even.target.value })
9
}
10
11
render() {
12
var options = ['Please select an option', 'One', 'Two', 'Three']
13
return (
14
<select value={this.state.value} onChange={this.handleChange}>
15
options.map((option, index) => <option value={index}>{option}</option>)
16
</select>
17
)
18
}
19
}

Multiple Inputs

1
class ControlledMultiple extends React.Component {
2
constructor(props) {
3
super(props)
4
this.state = { value: 'apple' }
5
this.handleChange = this.handleChange.bind(this)
6
}
7
handleChange(event) {
8
this.setState({ [event.target.name]: event.target.value })
9
}
10
render() {
11
var array = ['apple', 'banana', 'carrot', 'donuts']
12
var options = array.map((item) => <option value={item}>{item}</option>)
13
return (
14
<form>
15
<input
16
name="inputName"
17
type="input"
18
value={this.state.inputName}
19
onChange={this.handleChange}
20
/>
21
<textarea
22
name="textAreaName"
23
type="text"
24
value={this.state.textAreaName}
25
onChange={this.handleChange}
26
/>
27
28
<select
29
name="selectName"
30
value={this.state.selectName}
31
onChange={this.handleChange}
32
>
33
{options}
34
</select>
35
</form>
36
)
37
}
38
}

Tutorial

The Codepen for the Tutorial can be found here