03 RN - Class vs Functional
Class vs Functional
React and React Native has two approaches how to write components
- Class based – classical, full support
- Functional
- Initially limited, no state
- Hooks were implemented at the start of 2019
- Now the recommended way!
- Some edge cases still need class-based components (lifecycle events)
Class based component 1
- Class based component inherits from
Component<P={}, S={}>
- Declare interfaces for properties and state
- Properties – read-only data from parent component
- State – components internal data, set initial value in constructor
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | export interface Props {
label: string;
}
export interface State {
counter: number;
}
export class Hello extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = { counter: 0 };
}
...
|
Class based component 2
- Access both state and properties is provided via inheritance.
- this.props.xxx and this.state.xxx
- State – modify state with this.setState({….}) function. Only include changed properties as parameters – objects are merged.
- This will allow React to keep track of state changes and only update required UI components.
- Never modify state directly!
| render() {
return (
<View style={styles.root}>
<Button
title="+"
onPress={() => {
this.setState({ counter: this.state.counter + 1 });
}}
/>
|
Functional component
- Properties – declare interface, and specify props as parameter to function
- No this in functional components (no object instance here)
| export interface Props {
label: string;
}
const HelloFn = (props: Props): JSX.Element => (
<View style={styles.root}>
<Text style={styles.greeting}>{props.label}</Text>
</View>
);
|
Functional componet - hooks
State in functional components – use hooks!
- A Hook is a kind of function that lets you “hook into” React features.
- Most common hooks are
- useState
- useEffect
- useContext
- useReducer
Functional component - useState hook 1
const [state, setState] = useState(initialState);
- Returns a stateful value, and a function to update it.
- useState can be used several times, to create separate state containers.
1
2
3
4
5
6
7
8
9
10
11
12 | const HelloFn = (props: Props): JSX.Element => {
const [counter, setCounter] = useState(0);
return (
<View style={styles.root}>
<Button title="-" onPress={() => setCounter(counter - 1)} />
<Text style={styles.greeting}>
{props.label} {counter}
</Text>
<Button title="+" onPress={() => setCounter(counter + 1)} />
</View>
);
};
|
Functional component - - useState hook 2
- Unlike setState in class components, useState does not merge update objects. Use object spread syntax.
- Another option is useReducer, which is more suited for managing state objects that contain multiple sub-values.
- If the new state is computed using the previous state, you can pass a function to setState. The function will receive the previous value and return an updated value.