1. 程式人生 > >React Native 一個小專案其中一些主要功能實現 (頂部導航欄(可滑動),網路解析,上拉重新整理,下拉載入)

React Native 一個小專案其中一些主要功能實現 (頂部導航欄(可滑動),網路解析,上拉重新整理,下拉載入)

//網路解析
import React, { Component } from "react";
import { View, Text, TouchableOpacity } from "react-native";
import RefreshListView, { RefreshState } from "react-native-refresh-list-view";
import { withNavigation } from "react-navigation";
import Item from "./Item";
import { getData } from "./Fetch";
class List extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [],
      refreshState: RefreshState.Idle,
      page: 1,
      limit: 10,
      tab: props.tab
    };
  }
  requestData = async () => {
    let request = await fetch("https://cnodejs.org/api/v1/topics", {
      method: "GET"
    });
    let requestJson = await request.json();
    return requestJson.data;
  };
  requestFirstData = () => {
    try {
      this.setState(
        {
          refreshState: RefreshState.HeaderRefreshing,
          page: 1
        },
        async () => {
          let data = await this.requestData();
          this.setState({
            data: data,
            refreshState: RefreshState.Idle
          });
        }
      );
    } catch (error) {
      this.setState({
        refreshState: RefreshState.Failure
      });
    }
  };
  requestNextData = () => {
    try {
      this.setState(
        {
          refreshState: RefreshState.FooterRefreshing,
          page: this.state.page + 1
        },
        async () => {
          let data = await this.requestData();
          this.setState({
            data: [...this.state.data, ...data],
            refreshState:
              this.state.data.length > 30
                ? RefreshState.NoMoreData
                : RefreshState.Idle
          });
        }
      );
    } catch (error) {
      console.error(error);
    }
  };
  componentDidMount() {
    this.requestFirstData();
  }
  onHeader = () => {
    this.requestFirstData();
  };
  onFooter = () => {
    this.requestNextData();
  };
  renderItem = rowdata => {
    return (
      <TouchableOpacity
        onPress={() => {
          this.props.navigate("Detail", {
            content: rowdata.item.content
          });
        }}
      >
        <Item item={rowdata.item} />
      </TouchableOpacity>
    );
  };
  render() {
    return (
      <RefreshListView
        data={this.state.data}
        renderItem={this.renderItem}
        refreshState={this.state.refreshState}
        onHeaderRefresh={this.onHeader}
        onFooterRefresh={this.onFooter}
        keyExtractor={item => item.id}
      />
    );
  }
}
export default withNavigation(List);

//Item 頁面佈局
import React, { Component } from "react";
import { View, Text, Image, StyleSheet } from "react-native";

export default class Item extends Component {
  render() {
    return (
      <View style={styles.row}>
        <Image
          style={styles.img}
          source={{ uri: this.props.item.author.avatar_url }}
        />
        <View>
          <Text>{this.props.item.title}</Text>
          <Text>{this.props.item.author.loginname}</Text>
        </View>
      </View>
    );
  }
}
const styles = StyleSheet.create({
  row: {
    flexDirection: "row",
    padding: 20
  },
  img: {
    width: 80,
    height: 80
  }
});

//請求方式  GET
export const baseURL = "https://cnodejs.org/api/v1";
export const getURL = (url, obj) => {
  let objArray = [];
  Object.keys(obj).forEach(key => objArray.push(key + "=" + obj[key]));
  if (url.search(/\?/) === -1) {
    url += "?" + objArray.join("&");
  } else {
    url += "&" + objArray.join("&");
  }
  return url;
};
export const getData = async (url, obj) => {
  url = obj ? getURL(url, obj) : url;
  let request = await fetch(baseURL + url, { method: "GET" });
  let json = request.json();
  return json;
};