در این مقاله آموزشی قصد داریم آموزش حذف و اضافه کردن آیتم در یک برنامه React Native را به شما آموزش بدهیم. در این برنامه کاربر می تواند آیتم هایی (مثلا، نام مکان) را به برنامه اضافه کند و برنامه آن را در یک لیست نشان دهد، و همچنین می توان آیتم ها را از این لیست حذف کرد.
در این برنامه از کدهای سمت سرور استفاده نخواهیم کرد، چون فقط با قسمت client برنامه کار می کنیم و با قسمت backend برنامه کاری نداریم.
این برنامه را روی هر دو شبیه ساز سیستم عامل های ios و اندروید تست خواهیم کرد.
1-نصب React Native
2- افزودن TextBox و Button در فایل App.js
3- تعریف handler برای input و state
4-نمایش داده ها در FlatList
5- پیاده سازی قابلیت حذف آیتم
دستورات زیر را وارد کنید.
npm install -g react-native-cli
برای ایجاد یک برنامه جدید، کدهای زیر را اعمال کنید.
react-native init rncreate
حال، بعد از نصب باید این برنامه را در دو شبیه ساز مختلف باز کنیم.
برای تست این برنامه روی شبیه ساز ios دستورات زیر را در ترمینال وارد کنید.
react-native run-ios
در صورتیکه Xcode را به درستی پیکربندی کرده باشید، یک شبیه ساز ios باز و سرور توسعه هم راه اندازی می شود.
برای باز کردن پروژه در شبیه ساز اندروید، دستور زیر را وارد کنید.
react-native run-android
همچنین باید قبلا نرم افزار اندروید استودیو را نصب کرده و یک دیوایس مجازی درست کرده باشید.
در صورتی که خطای زیر را دریافت کردید:
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.
راه حل زیر را برای رفع این خطا دنبال کنید.
داخل فولدر اندروید یک فایل جدید به نام local.properties ایجاد کنید و کدهای زیر را در آن وارد کنید. در قسمت username، نام کاربری سیستم خود را وارد کنید.
sdk.dir = /Users/your username/Library/Android/sdk
حال دوباره دستور بالا را وارد کنید و می بینید که مشکل حل شده و شما خروجی زیر را می بینید.
شما می توانید از expo هم برای تست برنامه در شبیه ساز واقعی هم استفاده کنید. در صورتی که نمی دانید expo چیست،لطفا مقاله آموزش نصب React Native با استفاده از Expo را مطالعه بفرمایید.
در این مرحله می خواهیم یک فیلد متنی و یک دکمه برای افزودن نام مکان ها به برنامه اضافه کنیم. برای اینکار TextInput و Button ایجاد نمایید. سپس یک لایوت flexbox به برنامه اعمال کنید. برای اینکار کدهای زیر را در فایل App.js اضافه کنید.
// 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%' } });
خروجی کدهای بالا رو در هر دو شبیه ساز می بینید
در این مرحله یک state برای مدیریت وضعیت برنامه ایجاد می کنیم.
// App.js state = { placeName: '', places: [] } placeSubmitHandler = () => { console.log("Submitted"); }
در کد بالا ما مقادیر PlaceName را از ورودی گرفته و آنها را توسط یک حلقه تکرار در 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> ); } }
حالا، وقتی که شروع به تایپ داخل TextInput کنید، state بروزرسانی می شود و شما می توانید مقدارش را داخل فیلد متنی ببینید و زمانی که دکمه add را کلیک کنید، چک می کند که آیا مقدارش خالی است یا نه. اگر خالی نبود مقادیر داخل آرایه places اضافه می شوند.
داخل فولدر اصلی پروژه، یک فولدر به نام components ایجاد و داخل آن یک فایل به نام ListItem.js قرار دهید و کدهای زیر را داخل این فایل اضافه کنید.
// 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;
ما می خواهیم این کامپوننت را رندر و لیست مان را نمایش دهیم. دراینجا props ها را به عنوان پارامتر به آن پاس دادیم، و به این ترتیب می توانیم از طریق این props به مقادیر آرایه place دسترسی داشته باشیم و مقادیر آن را به درستی نمایش دهیم.
حال باید FlatList را داخل فایل App.js وارد تا بتوانیم کامپوننت بالا را رندر کنیم.
// 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%' } });
هنگامی که کاربر لیست را لمس کرد، برنامه آن آیتم را از لیست حذف می کند. ما قبلا از TouchableOpacity استفاده کرده ایم و دیدیم که یک آیتم را از لیست محو و آن را به طور دائم از لیست حذف می کند.
در اینجا ما باید رویداد onPress() را به TouchableOpacity اضافه کنیم. پس می توانیم مقدار ایندکس آن را به آن پاس داده و داده ها را بر اساس آن ایندکس فیلتر کند.
این رویداد را داخل فایل App.js ایجاد می کنیم و با استفاده از props می توانیم به آن در داخل فایل ListItem.js دسترسی داشته باشیم.
// 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%' } });
در کد بالا ما متد onDeleteItem() را تعریف کردیم و آن را از طریق props به عنصر فرزند پاس دادیم.حال باید کامپوننت ListItem.js را تغییر دهیم.
// 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;
در اینجا ما رویداد onPress را تعریف کردیم. بنابراین زمانی که کاربر آیتمی را از لیست حذف کند، لیست را بروزرسانی کرده و آیتم های باقی مانده را نمایش می دهد.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.