[React] Lists, Conditionals and HOC

Conditionals

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
return (
<div className="App">
<button onClick={this.toggleHandler}>Toggle</button>
<UserInput changed={this.eventHandler}></UserInput>
<UserOutput name={this.state.persons[0].name}/>

{
this.state.show ?
<div>
<UserOutput name={this.state.persons[1].name}/>
<UserOutput name={this.state.persons[2].name}/>
</div> : null
}
</div>
);
}

Javasript way:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
render() {
let output = null;

if (this.state.show) {
output = (
<div>
<UserOutput name={this.state.persons[1].name}/>
<UserOutput name={this.state.persons[2].name}/>
</div>
)
}
return (
<div className="App">
<button onClick={this.toggleHandler}>Toggle</button>
<UserInput changed={this.eventHandler}></UserInput>
<UserOutput name={this.state.persons[0].name}/>
{output}
</div>
);
}

Delete and Update elements

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// UserOutput.js
return (
<div className="UserOutput" onClick={props.click}>
<p>{props.name} output</p>
<input type="text" onChange={props.changed}/>
</div>
)

// App.js

class App extends Component {
state = {
persons: [
{id : '1', name: 'Max', age: 28},
{id : '2', name: 'Alex', age: 29},
{id : '3', name: 'Stephanie', age: 26}
],

show: true
}

eventHandler = (event, id) => {
const personIndex = this.state.persons.findIndex(p => {
return p.id === id;
});

const person = { // Create a new person object as a copy of
...this.state.persons[personIndex]
};

person.name = event.target.value; // Update name with event value

const persons = [...this.state.persons]; // create a new copy of persons
persons[personIndex] = person;

this.setState( // Update state
{persons: persons}
);
}

toggleHandler = () => {
this.setState({
show: !this.state.show
})
}

deleteHandler = (index) => {
// const posts = this.state.persons.slice(); // create a copy
// OR
const posts = [...this.state.persons];
console.log('should delete');
posts.splice(index, 1); // remove one element at index
this.setState( {
persons: posts
})
}

render() {
let output = null;

if (this.state.show) {
output = (
<div>
{this.state.persons.map((person, index) => {
return (
<div>
<UserOutput
name={person.name}
click={() => this.deleteHandler(index)}
changed={(event) => this.eventHandler(event, person.id)}
key={person.id}/>
</div>
)
})}
</div>
)
}
return (
<div className="App">
<button onClick={this.toggleHandler}>Toggle</button>
{output}
</div>
);
}
}

Render Adjacent JSX Elements

  1. With array

    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Person extends Component {
    render() {
    return [
    <p key="i1" >Item One</p>,
    <p key="i2" > Item Two</p>,
    <input key="i3"/>
    ]
    }
    }
  2. With a wrapping componnet (HOC)

    1
    2
    3
    4
    5
    6
    // Aux.js
    import React from 'react';

    const aux = props => props.children; // Return whatever between the <Aux> and <Aux/>

    export default aux;

Use HOC in components

1
2
3
4
5
6
7
8
9
10
11
12
13
// Component.js
import Aux from '../../hoc/Aux';

class Person extends Component {
render() {
return
(<Aux>
<p key="i1" >Item One</p>,
<p key="i2" > Item Two</p>,
<input key="i3"/>
</Aux>);
}
}

HOC

Higher order components Do not have representations, rather, they wrap other components inside to achieve some functionalities.

Use this component can remove the warpping HTML <div>, to bettern styling component

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
// Aux.js
import React from 'react';

const aux = (props) => props.children;

export default aux;

// Cockpit.js
render( //
<Aux>
<h1></h1>
<div></div>
</Aux>
)

//(After in React 16.2) built in Aux <>
render (
<>
<h1></h1>
<div></div>
</>
)

//(After in React 16.2) built in React.Fragment<>
render (
<React.Fragment>
<h1></h1>
<div></div>
</ React.Fragment>
)

Customized Higher Order Components

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// WithClass.js
import React from 'react';

const withClass = (props) => (
<div className={props.class}>
{props.children}
</div>
)

export default withClass;

// Component.js
import WithClass from './WithClass'; // Import a component

render() {
<WithClass class={classes.App}>
<h1></h1>
<div></div>
</WithClass>
}

If the HOC has logics (error handling etc), this would be a better approach

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

// Another Approach
// withClass.js
import withClass from 'withClass'; // Import a function

const withClass = (WrappedComponent, className) => {
return (props) => (
<div className={className}>
<WrappedComponent {...props}/> // pass props to wrapped component
</div>
)
}

export default withClass;

// Component.js

export default withClass(Person, classes.Person);