We will build a simple functionality where users can add and remove client-side places. It does not affect the server side because there is no backend. But you will learn how to create simple clientside and create and delete the data in the application. We will test both on Android and iOS Simulators.
React Native Create Delete Functionality
We start our project by installing React Native CLI globally on the Mac. You can skip the following command if you have already installed it.
Step 1: Install React Native.
Type the following command.
npm install -g react-native-cli
To create a new application, type the following command.
react-native init rncreate
After installing, we need to open this application in the two different Simulators.
For testing on the iOS simulator, type the following command.
react-native run-ios
If you have configured XCode correctly, then one iOS device will pop up, and the development server will start.
To open the project inside an Android device, type the following command.
react-native run-android
Also, you need to install Android Studio and create a virtual device.
If you have found an error like the following.
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring project ‘:app‘.
> SDK location not found. Define location with sdk.dir in the local.properties file or with an ANDROID_HOME environment variable.
Then the solution is the following.
Inside the Android folder, create a new file called local.properties and add the following code. Here, you can use your username, and I am using Mac.
sdk.dir = /Users/your username/Library/Android/sdk
Now, again run the above command and shall fix the problem.
You can also use an expo for this application. If you know nothing about the expo, please check out this How To Setup React Native Using Expo.
Step 2: Add Textbox and Button into the App.js.
We will add a text box and button to add places. So let us add the TextInput and Button. Also, we will add a flexbox layout. Write the following code inside the App.js file.
// App.js import React, {Component} from 'react'; import { StyleSheet, View, TextInput, Button } from 'react-native'; export default class App extends Component { placeSubmitHandler = () => { console.log("Submitted"); } render() { return ( <View style={ styles.container }> <View style = { styles.inputContainer }> <TextInput placeholder = "Seach Places" style = { styles.placeInput } ></TextInput> <Button title = 'Add' style = { styles.placeButton } onPress = { this.placeSubmitHandler } /> </View> </View> ); } } const styles = StyleSheet.create({ container: { paddingTop: 30, justifyContent: 'flex-start', alignItems: 'center', }, inputContainer: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', width: '100%' }, placeInput: { width: '70%' }, placeButton: { width: '30%' } });
Here is the output on both of the devices.
Step 3: Define the state and input handler.
Okay, now we need a state to manage. So we define the initial state like the following.
// App.js state = { placeName: '', places: [] } placeSubmitHandler = () => { console.log("Submitted"); }
So, we have taken placeName to display the value inside text input and places array on which we loop through and show all the places in FlatList.
// App.js import React, {Component} from 'react'; import { StyleSheet, View, TextInput, Button } from 'react-native'; export default class App extends Component { state = { placeName: '', places: [] } placeSubmitHandler = () => { if(this.state.placeName.trim() === '') { return; } this.setState(prevState => { return { places: prevState.places.concat({ key: Math.random(), value: prevState.placeName }) } }); } placeNameChangeHandler = (value) => { this.setState({ placeName: value }); } render() { return ( <View style={ styles.container }> <View style = { styles.inputContainer }> <TextInput placeholder = "Seach Places" style = { styles.placeInput } value = { this.state.placeName } onChangeText = { this.placeNameChangeHandler } ></TextInput> <Button title = 'Add' style = { styles.placeButton } onPress = { this.placeSubmitHandler } /> </View> </View> ); } }
So, when you start typing inside TextInput, the state is updated, and you can see the values inside text input, and when you press the add button, it checks if the value is empty or not.
If not empty, then add the values inside the places array. It is a very standard practice in React.js.
Step 4: Display the Data in the FlatList.
Inside the root, create one folder called components, and inside, create one file called ListItem.js and add the following code inside that file.
// ListItem.js import React from 'react'; import { View, Text, StyleSheet, TouchableOpacity } from 'react-native'; const ListItem = (props) => { return ( <TouchableOpacity> <View style = { styles.listItem }> <Text>{ props.placeName }</Text> </View> </TouchableOpacity> ); } const styles = StyleSheet.create({ listItem: { width: '100%', padding: 10, marginBottom: 10, backgroundColor: '#eee' } }); export default ListItem;
We created this file to render this component and display the list. Here, we have passed the props as an argument, so we can access the place values through props and display them in the proper format.
We must include the FlatList inside the App.js file and render the above component.
// App.js import React, {Component} from 'react'; import { StyleSheet, View, TextInput, Button, FlatList } from 'react-native'; import ListItem from './components/ListItem'; export default class App extends Component { state = { placeName: '', places: [] } placeSubmitHandler = () => { if(this.state.placeName.trim() === '') { return; } this.setState(prevState => { return { places: prevState.places.concat({ key: Math.random(), value: prevState.placeName }) } }); this.setState({ placeName: '' }); } placeNameChangeHandler = (value) => { this.setState({ placeName: value }); } placesOutput = () => { return ( <FlatList style = { styles.listContainer } data = { this.state.places } keyExtractor={(item, index) => index.toString()} renderItem = { info => ( <ListItem placeName={ info.item.value } /> )} /> ) } render() { return ( <View style={ styles.container }> <View style = { styles.inputContainer }> <TextInput placeholder = "Seach Places" style = { styles.placeInput } value = { this.state.placeName } onChangeText = { this.placeNameChangeHandler } ></TextInput> <Button title = 'Add' style = { styles.placeButton } onPress = { this.placeSubmitHandler } /> </View> <View style = { styles.listContainer }> { this.placesOutput() } </View> </View> ); } } const styles = StyleSheet.create({ container: { paddingTop: 30, justifyContent: 'flex-start', alignItems: 'center', }, inputContainer: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', width: '100%' }, placeInput: { width: '70%' }, placeButton: { width: '30%' }, listContainer: { width: '100%' } });
Step 5: Implement Delete Functionality.
When the user touches the list, it will remove the element from an array. We have already used TouchableOpacity. So it fades the particular item and removes it from the list permanently.
We need to add the onPress() event to TouchableOpacity. So we can pass the index value and filter out the data based on that index.
So, we need to add the event inside the first App.js file, and then through props, we can access that inside the ListItem.js file.
// App.js import React, {Component} from 'react'; import { StyleSheet, View, TextInput, Button, FlatList } from 'react-native'; import ListItem from './components/ListItem'; export default class App extends Component { state = { placeName: '', places: [] } placeSubmitHandler = () => { if(this.state.placeName.trim() === '') { return; } this.setState(prevState => { return { places: prevState.places.concat({ key: Math.random(), value: prevState.placeName }) } }); this.setState({ placeName: '' }); } placeNameChangeHandler = (value) => { this.setState({ placeName: value }); } placesOutput = () => { return ( <FlatList style = { styles.listContainer } data = { this.state.places } keyExtractor={(item, index) => index.toString()} renderItem = { info => ( <ListItem placeName={ info.item.value } onItemPressed={() => this.onItemDeleted(info.item.key)} /> )} /> ) } onItemDeleted = (key) => { this.setState(prevState => { return { places: prevState.places.filter(place => { return place.key !== key; }) } }) } render() { return ( <View style={ styles.container }> <View style = { styles.inputContainer }> <TextInput placeholder = "Seach Places" style = { styles.placeInput } value = { this.state.placeName } onChangeText = { this.placeNameChangeHandler } ></TextInput> <Button title = 'Add' style = { styles.placeButton } onPress = { this.placeSubmitHandler } /> </View> <View style = { styles.listContainer }> { this.placesOutput() } </View> </View> ); } } const styles = StyleSheet.create({ container: { paddingTop: 30, justifyContent: 'flex-start', alignItems: 'center', }, inputContainer: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', width: '100%' }, placeInput: { width: '70%' }, placeButton: { width: '30%' }, listContainer: { width: '100%' } });
We have defined the onDeleteItem() function and passed that as props to the Child Element. Now, we need to modify the ListItem.js component.
// ListItem.js import React from 'react'; import { View, Text, StyleSheet, TouchableOpacity } from 'react-native'; const ListItem = (props) => { return ( <TouchableOpacity onPress={ props.onItemPressed }> <View style = { styles.listItem }> <Text>{ props.placeName }</Text> </View> </TouchableOpacity> ); } const styles = StyleSheet.create({ listItem: { width: '100%', padding: 10, marginBottom: 10, backgroundColor: '#eee' } }); export default ListItem;
Here, we have defined the onPress event. So when the user presses the list item, it will get filtered out.
That’s it.
when i click on add button entered details should be listed in next page .for an example i have job experience details in one page ,i am filling it up and click ok it should be shown in nextpage .in 2nd page i click add it should come 1st page and viceversa.