React Native(“上”) 其中一些主要功能实现 (顶部导航栏(可滑动),网络解析,上拉刷新,下拉加载)

//fetch解析方式
export const baseURL = "https://cnodejs.org/api/v1";

// 拼接get参数
export const getURL = (url, params) => {
  let paramsArray = [];
  Object.keys(params).forEach(key => paramsArray.push(key + "=" + params[key]));
  if (url.search(/\?/) === -1) {
    url += "?" + paramsArray.join("&");
  } else {
    url += "&" + paramsArray.join("&");
  }
  return url;
};

//通过get获取数据,url是接口地址,obj是发送给后台的数据对象
export const getData = async (url, obj) => {
  url = obj ? getURL(url, obj) : url; //转换为需要的url
  let res = await fetch(baseURL + url, { method: "GET" });
  let json = res.json();
  return json;
};

//通过post获取数据,url是接口地址,obj是发送给后台的数据对象
export const postData = async (url, obj) => {
  let res = await fetch(baseURL + url, {
    method: "POST",
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json"
    },
    body: JSON.stringify(obj)
  });
  let json = await res.json();
  return json;
};


//Item 页面布局
import React, { Component } from "react";
import { Text, View, Image, StyleSheet } from "react-native";
import timeago from "timeago.js";

export default class App extends Component {
  render() {
    const timeagoInstance = timeago(); //格式日期
    return (
      <View style={styles.box}>
        <Text style={styles.title}>{this.props.item.title}</Text>
        <View style={styles.container}>
          <View style={styles.left}>
            <Image
              style={styles.avatar}
              source={{ uri: this.props.item.author.avatar_url }}
            />
            <View>
              <Text>{this.props.item.author.loginname}</Text>
              <Text>
                {timeagoInstance.format(this.props.item.create_at, "zh_CN")}
              </Text>
            </View>
          </View>

          <View>
            <Text>
              阅读量:
              {this.props.item.visit_count}
            </Text>
            <Text>
              回复量:
              {this.props.item.reply_count}
            </Text>
          </View>
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  box: {
    padding: 10,
    borderBottomWidth: 1,
    borderColor: "#ddd"
  },
  container: {
    flexDirection: "row",
    justifyContent: "space-between",
    alignItems: "center",
    marginTop: 5
  },
  left: {
    flexDirection: "row",
    alignItems: "center"
  },
  avatar: {
    width: 60,
    height: 60,
    borderRadius: 30,
    marginRight: 10
  },
  title: {
    fontWeight: "bold"
  }
});

//List网络解析
import React, { Component } from "react";
import { TouchableOpacity } from "react-native";
import { withNavigation } from "react-navigation";
import RefreshListView, { RefreshState } from "react-native-refresh-list-view";
import { getData } from "../comm/fetch";
import Item from "./Item";

class List extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [], //列表数据
      refershState: RefreshState.Idle, //默认刷新状态隐藏
      page: 1, //默认显示第一页
      tab: props.tab, //默认显示精华页面
      limit: 10 //每页显示10条数据
    };
  }

  requestData = async () => {
    //请求后台数据
    let obj = {
      page: this.state.page,
      tab: this.state.tab,
      limit: this.state.limit
    }; //从状态里面取发送给后台的参数
    let data = await getData("/topics", obj);
    return data.data;
  };

  requestFirstData = () => {
    try {
      this.setState(
        {
          refershState: RefreshState.HeaderRefreshing,
          page: 1
        },

        async () => {
          let data = await this.requestData();
          this.setState({
            data: data,
            refershState: RefreshState.Idle
          });
        }
      );
    } catch (error) {
      this.setState({
        refershState: RefreshState.Failure
      });
    }
  };

  requestNexData = () => {
    try {
      this.setState(
        {
          refershState: RefreshState.FooterRefreshing,
          page: this.state.page + 1
        },
        async () => {
          let data = await this.requestData();
          this.setState({
            data: [...this.state.data, ...data],
            refershState:
              this.state.data.length > 30
                ? RefreshState.NoMoreData
                : RefreshState.Idle
          });
        }
      );
    } catch (error) {
      this.setState({
        refershState: RefreshState.Failure
      });
    }
  };

  componentDidMount() {
    this.requestFirstData();
  }

  headerRefresh = () => {
    this.requestFirstData();
  };

  footerRefresh = () => {
    this.requestNexData();
  };

  renderItem = rowData => {
    return (
      <TouchableOpacity
        onPress={() =>
          this.props.navigation.navigate("Detail", {
            id: rowData.item.id,
            title: rowData.item.title
          })
        }
      >
        <Item item={rowData.item} />
      </TouchableOpacity>
    );
  };

  render() {
    return (
      <RefreshListView
        data={this.state.data}
        keyExtractor={item => item.id}
        renderItem={this.renderItem}
        refreshState={this.state.refershState}
        onHeaderRefresh={this.headerRefresh}
        onFooterRefresh={this.footerRefresh}
      />
    );
  }
}

export default withNavigation(List);


//TopNav顶部导航栏
import React from "react";
import { createTabNavigator } from "react-navigation";
import List from "./List";

const Good = () => {
  return <List tab="good" />;
};
const Share = () => {
  return <List tab="share" />;
};
const Ask = () => {
  return <List tab="ask" />;
};
const Job = () => {
  return <List tab="job" />;
};

const TopNav = createTabNavigator(
  {
    Good: {
      screen: Good,
      navigationOptions: {
        title: "精华"
      }
    },
    Share: {
      screen: Share,
      navigationOptions: {
        title: "分享"
      }
    },
    Ask: {
      screen: Ask,
      navigationOptions: {
        title: "问答"
      }
    },
    Job: {
      screen: Job,
      navigationOptions: {
        title: "工作"
      }
    }
  },
  {
    lazy: true, //懒加载
    tabBarPosition: "top", //切换条位置
    swipeEnabled: true, //是否可以滑动
    animationEnabled: true //滑动效果
  }
);

export default TopNav;


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的 react刷新和上的示例代码: ```jsx import React, { useState, useEffect } from 'react'; function App() { const [list, setList] = useState([]); const [loading, setLoading] = useState(false); const [hasMore, setHasMore] = useState(true); const [pageNumber, setPageNumber] = useState(1); useEffect(() => { // 列表 loadList(); }, []); const loadList = async () => { if (hasMore && !loading) { setLoading(true); const response = await fetch(`https://api.example.com/list?page=${pageNumber}`); const data = await response.json(); setLoading(false); setList(list => [...list, ...data]); setPageNumber(pageNumber => pageNumber + 1); setHasMore(data.length !== 0); } }; const handleScroll = event => { const { scrollTop, clientHeight, scrollHeight } = event.currentTarget; if (scrollHeight - (scrollTop + clientHeight) < 100 && hasMore) { loadList(); } }; const handleRefresh = async () => { setLoading(true); const response = await fetch(`https://api.example.com/list?page=1`); const data = await response.json(); setLoading(false); setList(data); setPageNumber(2); setHasMore(data.length !== 0); }; return ( <div onScroll={handleScroll}> <button onClick={handleRefresh}>刷新</button> {list.map(item => ( <div key={item.id}>{item.title}</div> ))} {loading && <div>中...</div>} {!loading && !hasMore && <div>没有更多数据</div>} </div> ); } export default App; ``` 这个示例代码演示了如何在 React实现刷新和上。在这个示例中: - `list` 用于存储的数据列表。 - `loading` 用于标记当前是否正在数据。 - `hasMore` 用于标记是否还有更多数据需要。 - `pageNumber` 用于记录当前的页数。 在页面完成后调用 `loadList` 函数第一页数据。`handleScroll` 函数用于处理滚动事件,当滚动到底部时,自动下一页数据。`handleRefresh` 函数用于处理下刷新事件,重新第一页数据。 当数据时,设置 `loading` 为 `true`,防止重复完成后,将新数据添到 `list` 列表中,更新页码和 `hasMore` 标记。如果没有更多数据可供,将 `hasMore` 设置为 `false`。 最后,将 `list` 显示为一系列列表项。如果正在数据,显示 `loading` 提示信息。如果没有更多数据可供,显示 `no more data` 提示信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值