React Native Development concepts - Components
Components

Through components, we can break the UI into reusable, independent pieces, and can think about each piece in isolation.
The components in React Native can be defined as functions or classes.
Traditionally class components are used as container components to handle state management and wrap child components and functional components are just used for display purposes calling functions from the parent components to handle user interactions or state updates.
Class components
To define the React component class, a React.component is extended.
To define a React.component subclass, we will implement the render method to display our UI components.
And several “lifecycle methods” that can be overridden to run code at a particular time in the whole process.
As most of the base components, that can be customized when they are created, with different parameters called props, our own components can also use props.
This allow us make a single component that is used in many different places in your app, with slightly different properties in each place. Refer to props.{NAME} in your functional components or this.props.{NAME} in your class.
Functional components
Functional components are simpler.
They originally did not manage their own state or have access to the lifecycle methods provided by React Native, they were more like a plain old JavaScript functions
since the introduction of React’s Hooks API in release 0.59 (March 2019), we can add state and some sort of life cycle management to function components witch allow us to write entire applications with just functions as React components.
functional components and hooks are the future-facing way of write react components,
Facebook recommends that you use functional components as much as possible, as they are more simple and easier to test as well.
Class Component Example
Taking our basic digital watch example,
we could create a component that contains the UI part of the watch and receives in Props the values to display managed in the caller page
with this we could as a simple example have different screens that obtain time and day in different formats or languages and all of them using the same component to display the watch UI
you can download the complete project here: Components Example (TypeScript)
this will be our component where for this example we will place the UI part of our watch and the CSS styles and will receive the values to be displayed in day and time as Props.
import React, {Component} from 'react';
import {View, Text, StyleSheet} from 'react-native';
interface IOwnProps {
currentTime: string;
currentDay: string;
handleStateChange: (value: string) => void;
}
type Props = IOwnProps;
export class WatchComponentView extends Component<Props> {
constructor(props: Props) {
super(props);
}
public componentDidMount() {
this.props.handleStateChange('test');
}
public render() {
return (
<View style={styles.containerCircle}>
<View style={styles.CircleShapeView}>
<Text style={styles.daysText}>{this.props.currentDay}</Text>
<Text style={styles.timeText}>{this.props.currentTime}</Text>
</View>
</View>
);
}
}
export const ComponentView = WatchComponentView;
// CSS styles used
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
headerText: {
fontSize: 30,
textAlign: 'center',
margin: 10,
color: 'black',
fontWeight: 'bold',
},
timeText: {
top: 90,
left: 60,
fontSize: 25,
color: '#C8C8C8',
},
daysText: {
top: 90,
left: 60,
color: '#C8C8C8',
fontSize: 25,
paddingBottom: 0,
},
containerCircle: {
top: 200,
left: 60,
flex: 1,
},
CircleShapeView: {
width: 270,
height: 270,
borderRadius: 580 / 2,
borderWidth: 10,
borderColor: '#C8C8C8',
backgroundColor: '#000000',
},
});
this will be our App.tsx where we will import our component, and call it passing the variables we need in props.
import React, {Component} from 'react';
import {ComponentView} from './WatchComponent';
interface IState {
currentTime: string;
currentDay: string;
dummy: string;
}
type Props = null;
export default class App extends Component<Props, IState> {
public daysArray: string[] = [
'sunday',
'monday',
'tuesday',
'wednesday',
'thursday',
'friday',
'saturday',
'sunday',
];
public timer: any = null;
constructor(props: Props) {
super(props);
this.state = {currentTime: '', currentDay: '', dummy: ''};
this.handleStateChange = this.handleStateChange.bind(this);
}
// helper method to get current day and time
getCurrentTime = () => {
let hour: string = new Date().getHours().toString();
let minutes: string = new Date().getMinutes().toString();
let seconds: string = new Date().getSeconds().toString();
let am_pm = 'pm';
if (parseInt(minutes, 10) < 10) {
minutes = '0' + minutes;
}
if (parseInt(seconds, 10) < 10) {
seconds = '0' + seconds;
}
if (parseInt(hour, 10) > 12) {
hour = (parseInt(hour, 10) - 12).toString();
}
if (parseInt(hour, 10) === 0) {
hour = '12';
}
if (new Date().getHours() < 12) {
am_pm = 'am';
}
this.setState({
currentTime: hour + ':' + minutes + ':' + seconds + ' ' + am_pm,
});
this.daysArray.map((item, key) => {
if (key === new Date().getDay()) {
this.setState({currentDay: item.toUpperCase()});
}
});
};
// called before component destroyed
componentWillUnmount() {
clearInterval(this.timer);
}
// called inmediately after component mounted
componentDidMount() {
this.timer = setInterval(() => {
this.getCurrentTime();
}, 1000);
}
public handleStateChange(value: string) {
this.setState({dummy: value});
}
// renders the content for the app
render() {
return (
<ComponentView
currentTime={this.state.currentTime}
currentDay={this.state.currentDay}
handleStateChange={this.handleStateChange}
/>
);
}
}
check full components sample code here:
Functional component examples
Below is a basic functional component example.
The definition of the component happens with just a JavaScript Function/cont which has to return JSX
import React from 'react';
function App() {
const greeting = 'Hello Function Component!';
return <h1>{greeting}</h1>;
}
export default App;
We can define functional components to be used inside another functional component
import React from 'react';
function App() {
return <Headline />;
}
function Headline() {
const greeting = 'Hello Function Component!';
return <h1>{greeting}</h1>;
}
export default App;
We can define React Function Component with props as below. In React, props are used to pass information from component to component.
Props are the React Function Component's parameters. Whereas the component can stay generic, we decide from the outside what it should render (or how it should behave). When rendering a component (e.g. Headline in App component), you can pass props as HTML attributes to the component. Then in the Function Component the props object is available as argument in the function signature.
import React from 'react';
function App() {
const greeting = 'Hello Function Component!';
return <Headline value={greeting} />;
}
function Headline(props) {
return <h1>{props.value}</h1>;
}
export default App;
JavaScript function can be expressed as lambda (arrow function). That's why a Function Component is sometimes called Arrow Function Components (or maybe also Lambda Function Component). Let's see our refactored React Component with an Arrow Function:
import React from 'react';
const App = () => {
const greeting = 'Hello Function Component!';
return <Headline value={greeting} />;
};
const Headline = ({ value }) => {
return <h1>{value}</h1>;
};
export default App;
Every functional component we have seen so far can be called Stateless Function Component. They just receive an input as props and return an output as JSX: (props) => JSX. The input, only if available in form of props, shapes the rendered output. These kind of components don't manage state and don't have any side-effects (e.g. accessing the browser's local storage). People call them Functional Stateless Components, because they are stateless and expressed by a function. However, React Hooks made it possible to have state in Function Components.
UseState Hook
The useState hook takes an initial state as parameter and returns an array which holds the current state as first item and a function to change the state as second item. We are using JavaScript array destructuring to access both items with a shorthand expression. In addition, the destructuring let's us name the variables ourselves.
import React, { useState } from 'react';
const App = () => {
return <Headline />;
};
const Headline = () => {
const [greeting, setGreeting] = useState(
'Hello Function Component!'
);
return (
<div>
<h1>{greeting}</h1>
<input
type="text"
value={greeting}
onChange={event => setGreeting(event.target.value)}
/>
</div>
);
};
export default App;
By providing an event handler to the input field, we are able to do something with a callback function when the input field changes its value. As argument of the callback function we receive a synthetic React event which holds the current value of the input field. This value is ultimately used to set the new state for the Function Component with an inline arrow function. We will see later how to extract this function from there.
As you have seen, React Hooks enable us to use state in React (Arrow) Function Components. Whereas you would have used a setState method to write state in a Class Component, you can use the useState hook to write state in a Function Component.
In the previous example you have used an onChange event handler for the input field. That's appropriate, because you want to be notified every time the internal value of the input field has changed. In the case of other HTML form elements, you have several other React event handlers at your disposal such as onClick, onMouseDown, and onBlur.
So far, we have used an arrow function to inline the event handler for out input field. What about extracting it as standalone function inside the component? It would become a named function then:
import React, { useState } from 'react';
const App = () => {
return <Headline />;
};
const Headline = () => {
const [greeting, setGreeting] = useState(
'Hello Function Component!'
);
const handleChange = event => setGreeting(event.target.value);
return (
<div>
<h1>{greeting}</h1>
<input type="text" value={greeting} onChange={handleChange} />
</div>
);
};
We can pass a function to a Child Component and handle what happens up in the Parent Component. You could also execute something in between in the Child Component (Headline component) for the onChangeHeadline function -- like trimming the value -- to add extra functionality inside the Child Component. That's how you would be able to call a Child Component's function from a Parent Component.
import React, { useState } from 'react';
const App = () => {
const [greeting, setGreeting] = useState(
'Hello Function Component!'
);
const handleChange = event => setGreeting(event.target.value);
return (
<Headline headline={greeting} onChangeHeadline={handleChange} />
);
};
const Headline = ({ headline, onChangeHeadline }) => (
<div>
<h1>{headline}</h1>
<input type="text" value={headline} onChange={onChangeHeadline} />
</div>
);
export default App;
useEffect hook
The useEffect hook has an important feature that allows functional components to have access to lifecycle methods to manage side-effects.
Remember, the lifecycle methods such as componentDidMount and componentDidUpdate, that we often use in a class component? we can achieve similar functionality in your React Native apps using useEffect instead of them.
in the below example useEffect is acting like componentDidUpdate
import React, {useEffect, useState} from 'react';
export const EffectDemo = () => {
//State
const [fullName, setFullName] = useState({name: 'name', familyName: 'family'});
const [title,setTitle] = useState('useEffect() in Hooks');
//useEffect
useEffect(() => {
console.log('useEffect has been called!');
setFullName({name:'kiko',familyName: 'Zanon'});
});
return(
<div>
<h1>Title: {title}</h1>
<h3>Name: {fullName.name}</h3>
<h3>Family Name: {fullName.familyName}</h3>
</div>
);
};
To tell useEffect to act like componentDidMount just pass an empty array
import React, {useEffect, useState} from 'react';
export const EffectDemo = () => {
//State
const [fullName, setFullName] = useState({name: 'name', familyName: 'family'});
const [title,setTitle] = useState('useEffect() in Hooks');
//useEffect
useEffect(() => {
setFullName({name:'kiko',familyName: 'Zanon'});
},[]); //Pass Array as second argument
return(
<div>
<h1>Title: {title}</h1>
<h3>Name: {fullName.name}</h3>
<h3>Family Name: {fullName.familyName}</h3>
</div>
);
};
useEffect can be used as well to perform API calls,
Download an example of API call using axios implemented with functional components and useEffect hook here:
see more details about components here:



