Topics -> react-native, appdevelopment, expo-client, todoapp
Preview Link -> TodoApp
Source Code Link -> GitHub
What We are going to do?
- Creating a basic structure.
- Adding event handler/functions to add and delete task.
- Adding Some stylings.
Installation of React Native Project using Expo-client
Assuming that you have Node 12 LTS or greater installed, you can use npm to install the Expo CLI command line utility:
npm install -g expo-cli
Then run the following commands to create a new React Native project called "TodoApp":
expo init AwesomeProject cd AwesomeProject npm start # you can also use: expo start
Components
Create a Component folder and add these components to it.
Header (header.js)
It will shows the navbar/header of the app.
import React, { Component } from "react";
import {
    StyleSheet,
    Text,
    View,
} from "react-native";
export default class header extends Component {
    render() {
        return (
            <View style={styles.header}>
            <Text style={styles.headerText}>Todo List</Text>
            </View>
        );
    }
}
                        Stylings used in Header Component
const styles = StyleSheet.create({
    header: {
    height: 80,
    backgroundColor: "#574b90",
    paddingTop:40,
    },
    headerText:{
    textAlign:'center',
    fontSize:24,
    color:'white'
    }
});
                  
                        Form Component (form.js)
This component will take the input from the user and add the task in TODO list.
import React, { Component } from "react";
import {
    StyleSheet,
    Text,
    TextInput,
    TouchableOpacity,
    View,
    Button,
} from "react-native";
export default class form extends Component {
    constructor(props) {
    super(props);
    this.state = { todo: "" };
    }
    todoTextHandler = (val) => {
    this.setState({ todo: val });
    };
    render() {
        return (
            <View>
            <TextInput
                multiline
                placeholder="write a todo"
                style={styles.todoInput}
                onChangeText={this.todoTextHandler}
            />
            <View style={styles.btn}>
                <Button
                title="Add todo"
                color="#574b90"
                onPress={() => {
                    console.log("todo", this.state.todo);
                    this.props.todoHandler(this.state.todo);
                }}
                />
            </View>
            </View>
        );
    }
}                 
                        Stylings used in Form Component
const styles = StyleSheet.create({
    todoInput: {
    borderColor: "#9e579d",
    backgroundColor:'#fc85ae',
    color:'#574b90',
    borderWidth: 3,
    height: 80,
    marginHorizontal: 20,
    marginTop: 10,
    textAlign: "center",
    fontSize: 18,
    fontWeight: "bold",
    },
    btn: {
    marginTop: 20,
    paddingHorizontal: 20,
    },
});   
                        TodoItem (todoItem.js)
This component will show all the tasks in TODO list and provide a delete button to delete them.
import React, { Component } from "react";
import { StyleSheet, Text, View } from "react-native";
import { MaterialIcons } from "@expo/vector-icons";
export default class todoItem extends Component {
    constructor(props) {
    super(props);
    }
    render() {
    return (
        <View style={styles.singleTodoContainer}>
        <MaterialIcons
            name="delete"
            size={25}
            onPress={() => this.props.todoRemoveHandler(this.props.item.key)}
        />
        <Text style={styles.todoText}>{this.props.item.text}</Text>
        </View>
    );
    }
}
                        Stylings used in Todo Component
const styles = StyleSheet.create({
    todoText: {
    flex:1,
    color: "#cabbe9",
    fontSize: 18,
    flexWrap: "wrap",
    },
    singleTodoContainer: {
    backgroundColor: "#9e579d",
    borderRadius:25,
    flexDirection: "row",
    marginVertical: 10,
    paddingVertical: 10,
    textAlign: "center",    
    },
});
                        
                        Editing the main App Component (App.js)
We will be adding event handlers to delete the tasks which are done
Importing required libraries
                            import { StatusBar } from "expo-status-bar";
import React, { useState } from "react";
import {
  Button,
  StyleSheet,
  Text,
  View,
  TextInput,
  ScrollView,
  FlatList,
  TouchableOpacity,
  Alert,
  Touchable,
  ImageBackground,
  Keyboard,
  TouchableWithoutFeedback,
} from "react-native";
import Header from "./components/header";
import TodoItem from "./components/todoItem";
import Form from "./components/form";
Adding dummy tasks
export default function App() {
  const [todo, setTodo] = useState([
    { text: "make readme.md", key: "1" },
    { text: "update readme.md", key: "2" },
    { text: "modify readme.md", key: "3" },
    { text: "delete readme.md", key: "4" },
  ]);
Adding conditionals to validate that the length of task must be 3.
  const todoHandler = (task) => {
    if (task.length > 3) {
      setTodo((prevTodo) => {
        return [{ text: task, key: Math.random().toString() }, ...prevTodo];
      });
    } else {
      Alert.alert("OOPS!", "Todo must be 3 chars long", [
        { text: "UNDERSTOOD", onPress: () => console.log("alert closed") },
      ]);
    }
  };
Event Handlers for deleting Task
  const todoRemoveHandler = (key) => {
    setTodo((prevTodo) => {
      return prevTodo.filter((todoitem) => todoitem.key != key);
    });
  };
Aligning the all components
  return (
    <TouchableWithoutFeedback
      onPress={() => {
        Keyboard.dismiss();
      }}
    >
      <View style={styles.container}>
        {/* header */}
        <Header />
        <ImageBackground source={require('./assets/backTodo.jpg')} style={styles.image}>
          {/* form */}
          <View>
            <Form todoHandler={todoHandler} />
          </View>
          {/* container */}
          <View style={styles.todoContainer}>
            <FlatList
              data={todo}
              keyExtractor={(item) => {
                return item.key;
              }}
              renderItem={({ item }) => (
                <TodoItem item={item} todoRemoveHandler={todoRemoveHandler} />
              )}
            />
          </View>
          
          {/* credits */}
          <View style={styles.introduction}>
            <Text style={styles.centerText}>
              This app is created by Praveen Chaudhary
            </Text>
          </View>
        </ImageBackground>
      </View>
    </TouchableWithoutFeedback>
  );
}
Adding styles
const styles = StyleSheet.create({
  container: {
    flex: 1,
    // backgroundColor: "#303a52",
  },
  todoContainer: {
    paddingHorizontal: 20,
  },
  introduction: {
    position: "absolute",
    bottom: 0,
    textAlign: "center",
    left: 0,
    right: 0,
    paddingBottom: 10,
    backgroundColor: "#574b90",
    alignSelf: "stretch",
  },
  centerText: {
    textAlign: "center",
    fontSize: 16,
    color: "#fc85ae",
  },
  image: {
    flex: 1,
    resizeMode: "cover",
  },
  btn: {
    marginTop: 20,
    paddingHorizontal: 20,
  },
  singleTodoContainer: {
    flexDirection: "row",
  },
});
                        All App Component together
import { StatusBar } from "expo-status-bar";
import React, { useState } from "react";
import {
  Button,
  StyleSheet,
  Text,
  View,
  TextInput,
  ScrollView,
  FlatList,
  TouchableOpacity,
  Alert,
  Touchable,
  ImageBackground,
  Keyboard,
  TouchableWithoutFeedback,
} from "react-native";
import Header from "./components/header";
import TodoItem from "./components/todoItem";
import Form from "./components/form";
export default function App() {
  const [todo, setTodo] = useState([
    { text: "make readme.md", key: "1" },
    { text: "update readme.md", key: "2" },
    { text: "modify readme.md", key: "3" },
    { text: "delete readme.md", key: "4" },
  ]);
  const todoHandler = (task) => {
    if (task.length > 3) {
      setTodo((prevTodo) => {
        return [{ text: task, key: Math.random().toString() }, ...prevTodo];
      });
    } else {
      Alert.alert("OOPS!", "Todo must be 3 chars long", [
        { text: "UNDERSTOOD", onPress: () => console.log("alert closed") },
      ]);
    }
  };
  const todoRemoveHandler = (key) => {
    setTodo((prevTodo) => {
      return prevTodo.filter((todoitem) => todoitem.key != key);
    });
  };
  return (
    <TouchableWithoutFeedback
      onPress={() => {
        Keyboard.dismiss();
      }}
    >
      <View style={styles.container}>
        {/* header */}
        <Header />
        <ImageBackground source={require('./assets/backTodo.jpg')} style={styles.image}>
          {/* form */}
          <View>
            <Form todoHandler={todoHandler} />
          </View>
          {/* container */}
          <View style={styles.todoContainer}>
            <FlatList
              data={todo}
              keyExtractor={(item) => {
                return item.key;
              }}
              renderItem={({ item }) => (
                <TodoItem item={item} todoRemoveHandler={todoRemoveHandler} />
              )}
            />
          </View>
          
          {/* credits */}
          <View style={styles.introduction}>
            <Text style={styles.centerText}>
              This app is created by Praveen Chaudhary
            </Text>
          </View>
        </ImageBackground>
      </View>
    </TouchableWithoutFeedback>
  );
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    // backgroundColor: "#303a52",
  },
  todoContainer: {
    paddingHorizontal: 20,
  },
  introduction: {
    position: "absolute",
    bottom: 0,
    textAlign: "center",
    left: 0,
    right: 0,
    paddingBottom: 10,
    backgroundColor: "#574b90",
    alignSelf: "stretch",
  },
  centerText: {
    textAlign: "center",
    fontSize: 16,
    color: "#fc85ae",
  },
  image: {
    flex: 1,
    resizeMode: "cover",
  },
  btn: {
    marginTop: 20,
    paddingHorizontal: 20,
  },
  singleTodoContainer: {
    flexDirection: "row",
  },
});
                        
                        Deployment
For deployment, We are using the Expo. For More Info
Web Preview / Output
 Web preview on deployment
                        Web preview on deployment
                        Placeholder text by Praveen Chaudhary · Images by Binary Beast