RefreshControl در React Native


کامپوننت RefreshControl با refreshControl={} prop در ListView استفاده میشه.این کامپوننت به ما این اجازه رو میده تا با Swipe Down اطلاعات JSON رو بروزرسانی کنیم.ساده ترین مثالی که برای درک این کامپوننت میشه زد،هنگام استفاده از اینستاگرام هست که با Swipe Down پست های جدید رو دریافت میکنیم.RefreshControl یک progress loading indicator است که به صورت اتوماتیک زمانی که شما با انگشتتان Swipe Down میکنید نمایش داده میشه و یک درخواست سمت سرور برای دریافت اطلاعات جدید میفرسته و بعد از دریافت اطلاعات دیگه نمایش داده نمیشه.
1.در دوره ساخت FLowerList سفارشی با استفاده از زبان PHP و پایگاه داده MySQL اطلاعات رو بصورت JSON از سرور دریافت میکردیم و در اپلیکیشن به نمایش میزاشتیم.
2.ایمپورت کردن کامپوننت های StyleSheet, ActivityIndicator, ListView, Text, View, Alert و RefreshControl در پروژه.
1 2 3 |
import React, { Component } from 'react'; import { StyleSheet, ActivityIndicator, ListView, Text, View, Alert, RefreshControl } from 'react-native'; |
3.تعریف ()constructor و ایجاد دو state به نام های isLoading و refreshing. از isLoading برای نمایش و پنهان کردن Activity indicator زمانی که اپلیکیشن برای اولین بار load میشه استفاده میشه و refreshing با کامپوننت RefreshControl استفاده میشه.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
constructor(props) { super(props); this.state = { isLoading: true, refreshing: false } this.webCall(); } |
4.تعریف یک تابع به نام ()GetItem.این تابع آیتم انتخاب شده از ListView رو بصورت یک alert dialog نمایش میده.
1 2 3 4 5 |
GetItem (fruit_name) { Alert.alert(fruit_name); } |
5.تعریف یک تابع به نام ()webCall.در این تابع ما سمت سرور درخواست میفرستیم و اطلاعات JSON دریافتی رو در dataSource ذخیره میکنیم.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
webCall=()=>{ return fetch('http:// 192.168.33.1/FruitsList.php') .then((response) => response.json()) .then((responseJson) => { let ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); this.setState({ isLoading: false, dataSource: ds.cloneWithRows(responseJson), }, function() { // In this block you can do something with new state. }); }) .catch((error) => { console.error(error); }); } |
6.تعریف یک تابع به نام ()ListViewItemSeparator.این تابع یک خط افقی بین آیتم های ListView ایجاد میکند.
1 2 3 4 5 6 7 8 9 10 11 |
ListViewItemSeparator = () => { return ( <View style={{ height: .5, width: "100%", backgroundColor: "#000", }} /> ); } |
7.تعریف یک تابع به نام ()onRefresh . درون این تابع ما تابع webCall رو فراخوانی میکنیم و خود تابع onRefresh رو از کامپوننت RefreshControl فراخوانی میکنیم.در این تابع ما ابتدا تمامی آیتم های ListView رو پاک میکنیم و ListView رو بصورت کامل خالی میکنیم و با فراخوانی تابع web call مجددا داده ها رو دریافت میکنیم.
1 2 3 4 5 6 7 8 9 |
nRefresh() { const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); this.setState({dataSource : ds.cloneWithRows([ ])}) this.webCall(); } |
8.ایجاد یک شرط IF در بلاک render’s برای نمایش activity indicator زمانی که اولین بار اپلیکیشن load میشود.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
render() { if (this.state.isLoading) { return ( <View style={{flex: 1, paddingTop: 20}}> <ActivityIndicator /> </View> ); } return ( ); } |
9.اضافه کردن کامپوننت ListView در بلاک render’s return با کامپوننت RefreshControl .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
render() { if (this.state.isLoading) { return ( <View style={{flex: 1, paddingTop: 20}}> <ActivityIndicator /> </View> ); } return ( <View style={styles.MainContainer}> <ListView dataSource={this.state.dataSource} renderSeparator= {this.ListViewItemSeparator} enableEmptySections = {true} renderRow={(rowData) => <Text style={styles.rowViewContainer} onPress={this.GetItem.bind(this, rowData.fruit_name)} >{rowData.fruit_name}</Text>} refreshControl={ <RefreshControl refreshing={this.state.refreshing} onRefresh={this.onRefresh.bind(this)} /> } /> </View> ); } |
10.ایجاد استایل
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
const styles = StyleSheet.create({ MainContainer :{ justifyContent: 'center', flex:1, margin: 10 }, rowViewContainer: { fontSize: 20, paddingRight: 10, paddingTop: 10, paddingBottom: 10, } }); |
11.کد کامل برنامه در فایل App.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
import React, { Component } from 'react'; import {StyleSheet, ActivityIndicator, ListView, Text, View, Alert, RefreshControl } from 'react-native'; export default class Project extends Component { constructor(props) { super(props); this.state = { isLoading: true, refreshing: false } this.webCall(); } GetItem (fruit_name) { Alert.alert(fruit_name); } webCall=()=>{ return fetch(http:// 192.168.33.1/FruitsList.php') .then((response) => response.json()) .then((responseJson) => { let ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); this.setState({ isLoading: false, dataSource: ds.cloneWithRows(responseJson), }, function() { // In this block you can do something with new state. }); }) .catch((error) => { console.error(error); }); } ListViewItemSeparator = () => { return ( <View style={{ height: .5, width: "100%", backgroundColor: "#000", }} /> ); } onRefresh() { const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); this.setState({dataSource : ds.cloneWithRows([ ])}) this.webCall(); } render() { if (this.state.isLoading) { return ( <View style={{flex: 1, paddingTop: 20}}> <ActivityIndicator /> </View> ); } return ( <View style={styles.MainContainer}> <ListView dataSource={this.state.dataSource} renderSeparator= {this.ListViewItemSeparator} enableEmptySections = {true} renderRow={(rowData) => <Text style={styles.rowViewContainer} onPress={this.GetItem.bind(this, rowData.fruit_name)} >{rowData.fruit_name}</Text>} refreshControl={ <RefreshControl refreshing={this.state.refreshing} onRefresh={this.onRefresh.bind(this)} /> } /> </View> ); } } const styles = StyleSheet.create({ MainContainer :{ justifyContent: 'center', flex:1, margin: 10 }, rowViewContainer: { fontSize: 20, paddingRight: 10, paddingTop: 10, paddingBottom: 10, } }); |
اسکرین شات:
دیدگاهتان را بنویسید