008.dva中使用网络请求

  • 安装axios
yarn add axios

在这里插入图片描述

  • 封装request.js

在这里插入图片描述

import axios from 'axios'
import Config from "react-native-config";

const service = axios.create({
    baseURL: Config.API_URL,
    timeout: 30000 // request timeout
})

service.interceptors.request.use(
    config => {
        if (config.params) {
            console.log(config.url, config.params)
        } else if (config.data) {
            console.log(config.url, config.data)
        } else {
            console.log(config.url)
        }
        return config
    },
    error => {
        console.log(error)
        return Promise.reject(error)
    }
)


service.interceptors.response.use(
    response => {
        const res = response.data
        console.log(res)
        if (res.code !== 200) {
            return Promise.reject(res)
        } else {
            return res
        }
    },
    error => {
        console.log('err' + error) // for debug
        return Promise.reject(error)
    }
)

export default service

在这里插入图片描述

import request from '@/config/request';

/**
 * 轮播图数据
 * @param params 
 * @returns 
 */
export async function getBannerList(): Promise<any> {
    return request({
        url: '/home/banner',
        method: 'GET',
    });
}
  • 在dva的model中使用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

import { Model, Effect } from 'dva-core-ts'
import { Reducer } from 'redux'

//导入service远端数据请求
import { getBannerList } from '@/pages/home/service'
import type { BannerType } from '@/pages/home/data'

type HomeState = {
    banners: BannerType[]
}

interface HomeModelType extends Model {
    namespace: string
    state: HomeState;//封装后台返回的数据
    effects: {
        asyncBannerList: Effect;
    };
    reducers: {
        getBannerList: Reducer<HomeState>,
    };
}

const HomeModel: HomeModelType = {
    namespace: 'home',
    state: {
        banners: []
    },
    //异步
    effects: {
        *asyncBannerList({ _ }, { call, put }) {
            const response = yield call(getBannerList)
            if (response && response instanceof Object) {
                yield put({
                    type: 'getBannerList',
                    payload: {
                        banners: response.data
                    }
                })
            }
        },
    },
    //同步
    reducers: {
        getBannerList(state, action) {
            return {
                ...state,
                ...action.payload,
            };
        },
    }
}

export default HomeModel

  • data.d.ts数据类型

/**
 * 获取banner
 */
export type BannerType = {
    id?: string,
    image?: string
}
  • 主页面调用dva,并将数据传递给轮播图组件

在这里插入图片描述
在这里插入图片描述

import React, { Component } from 'react';
import { View } from 'react-native';
import { RootStackNavigation } from '@/navigator/index'
// 使用dva
import { connect } from 'react-redux'
import type { ConnectedProps } from 'react-redux'
import type { RootState } from '@/models/index'

//轮播通用
import Carrousel from './components/carrousel'

// 关联dva
const mapStateToProps = ({ home, loading }: RootState) => {
    return {
        datas: home,//这里的home就是model中的namespace
        loading: loading.effects['home/asyncAdd'] //指定哪个方法需要显示loading判断
    }
}
//这里需要connect对象
const connector = connect(mapStateToProps)
//自动推导dva中的state类型
type ModelState = ConnectedProps<typeof connector>

// 这里需要继承ModelState ,区别于antd pro中的umi.js  umi不需要
// antd umi.js中使用dva:https://huangxiaoguo.blog.csdn.net/article/details/114890454
interface IProps extends ModelState {
    navigation: RootStackNavigation
}

class Home extends Component<IProps> {

    componentDidMount() {
        const { dispatch } = this.props
        dispatch({
            type: 'home/asyncBannerList'
        })
    }

    // 跳转详情页
    onPress = () => {
        const { navigation } = this.props
        navigation.navigate("Detail", { id: 18 })
    }
    render() {
        const { datas, loading } = this.props
        return (
            <View>
                <Carrousel banners={datas.banners} />
            </View>
        );
    }
}


// export default Home;
export default connector(Home)

  • 显示banner

在这里插入图片描述

import React, { Component } from 'react';
import SnapCarousel, { ParallaxImage, Pagination } from 'react-native-snap-carousel'
import type { AdditionalParallaxProps } from 'react-native-snap-carousel'
import { hp, viewportWidth, wp } from '@/utils/index'
import { StyleSheet, View } from 'react-native'
import { BannerType } from "../../data"


const sliderWidth = viewportWidth
const sideHeight = hp(26)
const itemWidth = wp(90) + wp(2) * 2


type CarouselProps = {
    banners: BannerType[]
}

class Carousel extends Component<CarouselProps>{
    state = {
        activeSlide: 0
    }
    onSnapToItem = (index: number) => {
        this.setState({
            activeSlide: index
        })
    }
    renderItem = ({ item }: { item: BannerType }, parallaxProps?: AdditionalParallaxProps) => {
        return <ParallaxImage
            source={{ uri: item.image }}
            style={styles.image}
            containerStyle={styles.imageContainer}
            parallaxFactor={0.8}//默认0.3
            showSpinner
            spinnerColor='rgba(0,0,0,0.25)'
            {...parallaxProps} />
    }
    get pagination() {
        const { activeSlide } = this.state
        const { banners } = this.props
        return (
            <View style={styles.paginationWarpper}>
                <Pagination
                    containerStyle={styles.paginationContainer}
                    dotContainerStyle={styles.dotContainer}
                    dotStyle={styles.dot}
                    inactiveDotScale={0.7}
                    inactiveDotOpacity={0.4}
                    activeDotIndex={activeSlide}
                    dotsLength={banners.length} />
            </View>
        )
    }
    render() {
        const { banners } = this.props
        return (
            <View>
                <SnapCarousel data={banners}
                    renderItem={this.renderItem}
                    sliderWidth={sliderWidth}
                    itemWidth={itemWidth}
                    hasParallaxImages
                    loop
                    autoplay
                    onSnapToItem={this.onSnapToItem}
                />
                {this.pagination}
            </View>
        );
    }
}

const styles = StyleSheet.create({
    imageContainer: {
        width: itemWidth,
        height: sideHeight,
        borderRadius: 8
    },
    image: {
        ...StyleSheet.absoluteFillObject,
        resizeMode: 'cover'
    },
    paginationWarpper: {
        position: 'relative',
        justifyContent: 'center',
        alignItems: 'center'
    },
    paginationContainer: {
        position: 'absolute',
        top: -25,
        backgroundColor: 'rgba(0,0,0,0.15)',
        paddingHorizontal: 3,
        paddingVertical: 4,
        borderRadius: 8
    },
    dotContainer: {
        marginHorizontal: 6
    },
    dot: {
        width: 6,
        height: 6,
        borderRadius: 3,
        backgroundColor: 'rgba(255,255,255,0.75)'
    }
})

export default Carousel;
  • 请求数据格式
{
  "code": 200,
  "data": [
    {
      "id": "2131231231232",
      "image": "https://unsplash.it/1920/1080?random&56"
    },
    {
      "id": "2131231233432",
      "image": "https://unsplash.it/1920/1080?random&25"
    },
    {
      "id": "21312343231232",
      "image": "https://unsplash.it/1920/1080?random&3"
    },
    {
      "id": "2131236631232",
      "image": "https://unsplash.it/1920/1080?random&33"
    },
    {
      "id": "2131987831232",
      "image": "https://unsplash.it/1920/1080?random&22"
    },
    {
      "id": "2131237651232",
      "image": "https://unsplash.it/1920/1080?random&51"
    }
  ],
  "message": "获取数据成功"
}
  • 效果

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值