آموزش حذف و اضافه کردن آیتم ها در React Native

29 مرداد 1397
react-native-logo

در این مقاله آموزشی قصد داریم آموزش حذف و اضافه کردن آیتم در یک برنامه React Native را به شما آموزش بدهیم. در این برنامه کاربر می تواند آیتم هایی (مثلا، نام مکان) را به برنامه اضافه کند و برنامه آن را در یک لیست نشان دهد، و همچنین می توان آیتم ها را از این لیست حذف کرد.

در این برنامه از کدهای سمت سرور استفاده نخواهیم کرد، چون فقط با قسمت client برنامه کار می کنیم و با قسمت backend برنامه کاری نداریم.

این برنامه را روی هر دو شبیه ساز سیستم عامل های ios و اندروید تست خواهیم کرد.

سرفصل های این آموزش

1-نصب React Native

2- افزودن TextBox و Button در فایل App.js

3- تعریف handler برای input و state

4-نمایش داده ها در FlatList

5- پیاده سازی قابلیت حذف آیتم

1- نصب React Native

دستورات زیر را وارد کنید.

npm install -g react-native-cli

برای ایجاد یک برنامه جدید، کدهای زیر را اعمال کنید.

react-native init rncreate

نصب react native

حال، بعد از نصب باید این برنامه را در دو شبیه ساز مختلف باز کنیم.

برای تست این برنامه روی شبیه ساز ios دستورات زیر را در ترمینال وارد کنید.

react-native run-ios

در صورتیکه Xcode  را به درستی پیکربندی کرده باشید، یک شبیه ساز ios باز و سرور توسعه هم راه اندازی می شود.

نمایش برنامه در شبیه ساز 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 را مطالعه بفرمایید.

2- افزودن Textbox و Button به فایل App.js

در این مرحله می خواهیم یک فیلد متنی و یک دکمه برای افزودن نام مکان ها به برنامه اضافه کنیم. برای اینکار 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%'
      }
});

خروجی کدهای بالا رو در هر دو شبیه ساز می بینید

نمایش برنامه در هر شبیه ساز اندروید و ios در rect native

3- تعریف handler برای state و input

در این مرحله یک 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 اضافه می شوند.

4- نمایش داده ها در FlatList

داخل فولدر اصلی پروژه، یک فولدر به نام 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%'
      }
});

نمایش آیتم ها در لیست react native

5-پیاده سازی قابلیت حذف آیتم ها

هنگامی که کاربر لیست را لمس کرد، برنامه آن آیتم را از لیست حذف می کند. ما قبلا از 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 را تعریف کردیم. بنابراین زمانی که کاربر آیتمی را از لیست حذف کند، لیست را بروزرسانی کرده و آیتم های باقی مانده را نمایش می دهد.

نویسنده شوید
دیدگاه‌های شما (1 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

محمد
21 تیر 1399
در قسمت 5 فرمودید که قبلا از TouchableOpacity استفاده کردید و یک آیتم را بطور دائم از لیست حذف کردید؟ این در کدام بخش از آموزش هست؟ من الان یه آرایه عددی دارم و میخواهم که روی هر عدد کلیک شد اون از لیست حذف بشه . منتها این کار انجام نمیشه. میشه لطفا راهنماییم کنید؟

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.