React Native todo app
Useful links:
https://facebook.github.io/react-native/docs/getting-started
http://www.reactnativeexpress.com/data_component_state
In this article, we will be creating a mobile application base on the React Native framework and expo CLI to see the result of our work.
In this diagram we can see how the basic concept looks like:
Let’s get started and prepare the environment for our work.
npm install -g expo-cli expo init AwesomeProject cd AwesomeProject npm start # you can also use: expo start
The next step is to go to the expo website to create an account download app on the mobile devices register account and we are ready to go.
Let’s see how the code looks like let’s start from app.js:
app.js
import React, { Component } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import List from './List'
import Input from './Input'
import Title from './Title'
export default class App extends Component {
state = {
todos:[
'click to remove','Learn React Native','Write Code','Ship App']
}
onAddTodo = (text) => {
const {todos} = this.state
this.setState({
todos:[text, ...todos]
})
}
onRemoveTodo = (index) => {
const {todos} = this.state
this.setState({
todos: todos.filter((todo, i) => i !== index),
})
}
render(){
const { todos } = this.state
return (
<View>
<Title>
To-do List
</Title>
<Input
placeholder={'Type a todo, then hit enter!'}
onSubmitEditing={this.onAddTodo}
/>
<List
list={todos}
onPressItem={this.onRemoveTodo}
/>
</View>
);
}
}
In this file, we have a standard react structure we define the class which is exported with the state where are example todos, function to add and remove todos. Next, we render 3 components Title, Input, and List. In the title component we pass childer string and it looks like this:
title.js
import React, { Component } from 'react'
import { View, Text, StyleSheet } from 'react-native'
export default class Title extends Component{
render(){
const { children } = this.props
return(
<View style={styles.header}>
<Text style={styles.title}>{children}</Text>
</View>
)
}
}
const styles = StyleSheet.create({
header:{
backgroundColor:'skyblue',
padding:15,
},
title:{
textAlign:'center',
color:'white',
}
})
The big advantage of react native is integrated StyleSheet class which we can use to build styles for this component. And string retrieves from props and display in a Text element.
Next, we have an input component and as an argument we pass two things:
placeholder when the input field is empty and function onAddTodo but we don’t invoke it jet it will be invoked by onpress event in input component.
Input.js
import React, { Component } from 'react'
import { TextInput, StyleSheet } from 'react-native'
export default class Input extends Component{
state = {
text:'',
}
onChangeText = text => this.setState({ text })
onSubmitEditing = () => {
const { onSubmitEditing } = this.props
const { text } = this.state
if(!text) return
onSubmitEditing(text)
this.setState({ text: '' })
}
render(){
const { placeholder } = this.props
const { text } = this.state
return(
<TextInput
style={styles.input}
value={text}
placeholder={placeholder}
onChangeText={this.onChangeText}
onSubmitEditing={this.onSubmitEditing}
/>
)
}
}
const styles = StyleSheet.create({
input:{
padding:15,
height:50,
}
})
The interesting thing in this component is how input value is two-way data binding on change the value is added and then update in the state that we have always the right text.
Next component is our List.js where we can display todo and can delete it:
List.js
import React, { Component } from 'react'
import { View, TouchableOpacity, Text, StyleSheet } from 'react-native'
export default class List extends Component{
renderItem = (text, i) => {
const { onPressItem } = this.props
return(
<TouchableOpacity style={styles.item} key={i} onPress={() => onPressItem(i)}>
<Text>{text}</Text>
</TouchableOpacity>
)
}
render(){
const { list } = this.props
return <View>{list.map(this.renderItem)}</View>
}
}
const styles = StyleSheet.create({
item:{
backgroundColor:'whitesmoke',
marginBottom: 5,
padding:15,
}
})
The trick in this component is to use index of map function in renderItem function which allowed us to track which element should be deleted.
And that’s more basic react native todo app.
Book to read: