Studying React-Native is like — 8 (Delete elements, Modal, Adding Image)

HaeChan Jung
5 min readJan 14, 2024

--

Let’s add a function that remove elements of array when it is clicked.

This is App.js

import { useState } from 'react';
import { StyleSheet, Text, View, FlatList} from 'react-native';
import GoalItem from './components/GoalItem';
import GoalInput from './components/GoalInput';

export default function App() {

const [courseGoals, setCourseGoals] = useState([]);

function addGoalHandler(enteredGoalText){
setCourseGoals((currentCourseGoals) => [
...currentCourseGoals,
{text : enteredGoalText, id : Math.random().toString()},]) // add elements to courseGoals.
};

function deleteGoalHandler(a){
setCourseGoals(currentCourseGoals => {
return currentCourseGoals.filter((goal) => goal.id !== a);
})
}

return (
<View style={styles.appContainer}>
<GoalInput onAddGoal={addGoalHandler}/>
<View style={styles.goalsContainer}>
<FlatList data={courseGoals} renderItem={(itemData) => {
return (
<GoalItem text={itemData.item.text}
id={itemData.item.id}
onDeleteItem = {deleteGoalHandler}/>
)
}}
keyExtractor={(item, index) =>{
return item.id;
} }/>
</View>
</View>

);
}

const styles = StyleSheet.create({
appContainer: {
flex : 1,
paddingTop : 50,
paddingHorizontal : 15,
textAlign : 'center'
},
inputContainer : {
flex : 1,
flexDirection: 'row',
justifyContent : 'space-between',
alignItems : 'center',
marginBottom : 20,
borderBottomWidth : 1,
borderBottomColor : 'skyblue'
},

textInput : {
borderWidth : 1,
borderColor : '#cccccc',
width:'60%',
marginRight : 8,
padding : 8
},
goalsContainer: {
flex : 5
},

});

This is GoalItem.js

import { StyleSheet, View, Text , Pressable} from "react-native"

function GoalItem(props) {

return (

<View style={styles.goalItem} >
<Pressable
onPress={props.onDeleteItem.bind(this,props.id)}
style = {({pressed}) => pressed && styles.pressedItem}>
<Text style={styles.goalText}>{props.text}</Text>
</Pressable>
</View>


)
}

export default GoalItem

const styles = StyleSheet.create({
goalItem:{
margin : 8,
padding : 8,
borderRadius : 6,
backgroundColor : 'pink',
color: 'white'
},
pressedItem: {
opacity : 0.5
},
goalText : {
color : 'white',
}
});

I made deleteGoalHandler to remove item from array. Using fliter to get rid of target items inside of array.

function deleteGoalHandler(a){
setCourseGoals(currentCourseGoals => {
return currentCourseGoals.filter((goal) => goal.id !== a);
})
}

And i add props that pointing ‘itemData.item.id’. So, deleteGoalHandler can use function argument.

Look at this GoalItem.js code.

onPress={props.onDeleteItem.bind(this,props.id)}

I added Pressible components to control when item is pressed.

Inside of this tag, onPress is a method when item is clicked. And we difine onDeleteItem props as deleteItemHandler function but how we can get ‘id’ argument from there?

That’s why we added props.id by using bind. bind allow function to get it’s second argument. so we can use props.id from onDeleteIe.

Moreover, i want to make a ripple effect when i click a button.

To use this effect, we have to use Pressable component. Inside of View component in GoalItem.js, we have to put Pressible component like this.

<View style={styles.goalItem} >
<Pressable
onPress={props.onDeleteItem.bind(this,props.id)}
<Text style={styles.goalText}>{props.text}</Text>
</Pressable>
</View>

But to use launch this effect, we have to add ‘style’ function inside of Pressable. Let’s add style in here.

<View style={styles.goalItem} >
<Pressable
onPress={props.onDeleteItem.bind(this,props.id)}
style = {({pressed}) => pressed && styles.pressedItem}>
<Text style={styles.goalText}>{props.text}</Text>
</Pressable>
</View>

We added style in the Pressable. so when pressed is true, styles.pressedItem is working.

Now let’s improve the overall look and feel of this application like modal effects.

We gonna import ‘Modal’ component to GoalInput.js because we gonna make Modal to GoalInput.

import { View, StyleSheet, TextInput, Button, Modal } from "react-native";

Let’s add Modal component in GoalInput.js and complete code is below.

import { View, StyleSheet, TextInput, Button, Modal } from "react-native";
import { useState } from "react";

function GoalInput (props){
const [enteredGoalText, setEnteredText] =useState("");

function textInputHandler(enteredText) {
setEnteredText(enteredText);
};

function addGoalHandler(){
props.onAddGoal(enteredGoalText);
setEnteredText('')
}

return (
<Modal visible={props.define} animationType="slide">
<View style={styles.inputContainer}>
<TextInput
style={styles.textInput}
placeholder='this is input!'
onChangeText={textInputHandler}
value={enteredGoalText} />
<View style={styles.buttonContainer}>
<View style={styles.button}>
<Button title='add your thing!' color='#006666'
onPress={addGoalHandler}/>
</View>
<View style={styles.button2}>
<Button title="Cancel" color='#006666' onPress={props.onCancel}/>
</View>

</View>

</View >
</Modal>
)

};

export default GoalInput

const styles = StyleSheet.create({
inputContainer : {
flex : 1,
justifyContent : 'center',
alignItems : 'center',
marginBottom : 20,
borderBottomWidth : 1,
borderBottomColor : 'skyblue'
},

textInput : {
borderWidth : 1,
borderColor : '#cccccc',
width:'60%',
marginRight : 8,
padding : 8
},

buttonContainer:{
flexDirection : 'row'

},
button :{
width : '40%',
marginTop : 10,
marginHorizontal : 8,
backgroundColor : 'pink',
borderRadius: 10
},
button2 : {
width : '25%',
marginTop : 10,
backgroundColor : 'pink',
borderRadius : 10
}
})

We see that Modal needs visible to show or not and defined animationType to slide or fade, none. I’ve made two button components and wrap it with a View components to make styles. Second button added is a cancel Modal button that close Modal. It gets props.onCancel as a props. Then what is onCancel?

This is App.js

export default function App() {

const [modalIsVisible, setModalIsVisible] = useState(false);
const [courseGoals, setCourseGoals] = useState([]);

function startAddGoalHandler(){
setModalIsVisible(true);
}

function endAddGoalHandler(){
setModalIsVisible(false);
}
function addGoalHandler(enteredGoalText){
setCourseGoals((currentCourseGoals) => [
...currentCourseGoals,
{text : enteredGoalText, id : Math.random().toString()},]) // add elements to courseGoals.
};

function deleteGoalHandler(a){
setCourseGoals(currentCourseGoals => {
return currentCourseGoals.filter((goal) => goal.id !== a);
})
}

return (
<View style={styles.appContainer}>
<Button title='Add New Goal' color='black' onPress={startAddGoalHandler}/>
<GoalInput onAddGoal={addGoalHandler}
define={modalIsVisible}
onCancel = {endAddGoalHandler}/>
<View style={styles.goalsContainer}>
<FlatList data={courseGoals} renderItem={(itemData) => {
return (
<GoalItem text={itemData.item.text}
id={itemData.item.id}
onDeleteItem = {deleteGoalHandler}/>
)
}}
keyExtractor={(item, index) =>{
return item.id;
} }/>
</View>
</View>

);
}

I made a function endAddGoalHandler to close the Modal. So, when endAddGoalHandler is called, display of Moda is closed.

So far, we made lots of things like opening and closing Modals and let’s work with Image.

I’ll put image on the TextInput. To use image, imma import Image component.

import { View, StyleSheet, TextInput, Button, Modal,Image } from "react-native";

And I’ll add this code on the TextInput component.

<Image style={styles.image} source={require('../assets/images/goal.png')} />

I made a ‘images’ folder in the assets and add goal.png into images. To bring image source, i’ll use require to get image file.

Moreover, i fixed some style sources and Final goal list app is done now!

If you want to get all source, feel free to text me on the comment!

Thank you for watching my stuff!

--

--

HaeChan Jung

Thank you for visiting! Currently, Senior Computer Science student so far . Educated in machine learning and blockchain at university. Using C, C++, and Python.