笔记
React-Native + ts + mobx 项目
1.构建一个RN项目
npm install -g expo-cli
expo init foodrn-app
cd foodrn-app
npm start # 也可以使用命令: expo start
2.写底部tab栏
yarn add react-native-tab-navigator -S
yarn add @types/react-native-tab-navigator
创建首页
//app.tsx
import React from 'react';
import Index from './pages/index/Index'
export default function App() {
return (
);
}
//index/Index.tsx
// pages/index/Index.tsx
import React, { Component } from 'react'
import { Text, View, Image, StyleSheet } from 'react-native'
// 引入tab插件
import TabNavigator from 'react-native-tab-navigator'
import cookbook from './../../assets/images/cookbook.png'
import cookbookActive from './../../assets/images/cookbook-active.png'
import kind from './../../assets/images/menu.png'
import kindActive from './../../assets/images/menu-active.png'
import location from './../../assets/images/location.png'
import locationActive from './../../assets/images/location-active.png'
import more from './../../assets/images/more.png'
import moreActive from './../../assets/images/more-active.png'
import styles from './style_index'
interface Props {
}
interface State {
selectedTab: string
}
export default class Index extends Component {
constructor(props: Props) {
super(props)
}
state: State = {
selectedTab:'home'
}
componentDidMount() {
}
render() {
return (
}
renderSelectedIcon={() => }
onPress={() => this.setState({ selectedTab: 'home' })}>
菜谱大全
}
renderSelectedIcon={() => }
onPress={() => this.setState({ selectedTab: 'kind' })}>
分类
}
renderSelectedIcon={() => }
onPress={() => this.setState({ selectedTab: 'location' })}>
地图
}
renderSelectedIcon={() => }
onPress={() => this.setState({ selectedTab: 'more' })}>
更多
)
}
}
抽离出来的样式
//index/index_style.ts
import { StyleSheet } from 'react-native'
export default StyleSheet.create({
titleStyle: {
color:'#666'
},
tabBarStyle: {
paddingBottom: 34,
height: 80
},
selectedTitleStyle: {
color: '#000'
},
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
icon: {
height:30,
width: 30
}
})
需要引用图片所以需要配置一个images.d.ts文件
//images.d.ts
declare module '*.png'
declare module '*.jpg'
declare module '*.jpeg'
declare module '*.svg'
declare module '*.gif'
declare module '*.webp'
4. tabbar 的兼容处理
安装 expo-device
npm i expo-device -S
// 载入模块
import * as Device from 'expo-device'
// 在 TabNavigator 上修改 tabBarStyle
// **** 将刘海屏的手机名称依次写进去 ****
>const arr = ["iPhone 12 Pro Max"]
tabBarStyle = { arr.includes((Device.deviceName as string)) ? styles.tabBarStyle : {} }
5.引入antd
yarn add @ant-design/react-native
按需加载
yarn add babel-plugin-import
// .babelrc or babel-loader option
{
"plugins": [
["import", { libraryName: "@ant-design/react-native" }] // 与 Web 平台的区别是不需要设置 style
]
}
然后再模块里面就可以使用了
import { Button } from '@ant-design/react-native'
6. 引入轮播组件
创建一个Home.tsx文件放轮播图和热门分类
//home/Home.tsx
import React, { Component } from 'react'
import Swiper from './Swiper'
import HotCate from './HotCate'
interface Props {
}
interface State {
}
class Home extends Component< Props, State > {
render (){
return(
<>
{/* */}
>
)
}
}
export default Home
轮播图组件
需要下载
yarn add @react-native-community/viewpager
//home/Swiper.tsx
import React, { Component } from 'react'
import { View, Text } from 'react-native'
import { Carousel } from '@ant-design/react-native'
import styles from './style_index'
interface Props {
}
interface State {
}
class Swiper extends Component< Props, State > {
render () {
return (
Carousel 1
Carousel 2
Carousel 3
Carousel 4
Carousel 5
)
}
}
export default Swiper
7. 获取轮播图数据
封装一个fetch请求文件
//utils/request.ts
export const get = (url: string) => {
return fetch(url, {
method: 'get'
})
.then(response => response.json())
.then(result => {
return result.data
})
}
再需要使用的组件中引入
//Swiper.tsx
import React, { Component } from 'react'
import { View, Text, Image } from 'react-native'
import { Carousel } from '@ant-design/react-native'
//数据请求
import { get } from './../../utils/request'
import styles from './style_index'
interface Banner {
bannerid: string,
bannerimg: string
}
interface Props {
}
interface State {
list: Array
}
class Swiper extends Component< Props, State > {
state: State = {
list: []
}
async componentDidMount () {
let list = await get('http://10.20.159.162:3001/api/banner')
console.log(list)
this.setState({list})
}
render () {
return (
{
this.state.list.map(item => {
return (
)
})
}
)
}
}
export default Swiper
文件用到的样式封装
//home/style_index.ts
import React, { Component } from 'react'
import { View, Text, Image } from 'react-native'
import { Carousel } from '@ant-design/react-native'
// 数据请求
import { get } from './../../utils/request'
import styles from './style_index'
// 定义获取到的数据类型
interface Banner {
bannerid: string,
bannerimg: string
}
interface Props {
}
interface State {
list: Array
}
class Swiper extends Component< Props, State > {
state: State = {
list: []
}
async componentDidMount () {
let list = await get('http://10.20.159.162:3001/api/banner')
console.log(list)
this.setState({list})
}
render () {
return (
{
this.state.list.map(item => {
return (
)
})
}
)
}
}
export default Swiper
8. Mock模拟数据
cnpm i json-server -g
切换接口
切换接口//单接口
json-server cookbook-hotcat.json --watch --port=3003
// 让手机可见需要更改ip
json-server mock.js --watch --host=10.20.159.162
渲染页面 HotCate.tex
import React, { Component } from 'react'
import { View, Text } from 'react-native'
// 请求数据
import { get } from './../../utils/request'
// 导入宫格布局
import { Grid } from '@ant-design/react-native'
import styles from './style_index'
interface HotCate {
img: string,
title: string,
}
interface Props {
}
interface State {
list: Array
}
class HotCate extends Component< Props, State > {
// 数据
state: State = {
list:[]
}
// 数据
async componentDidMount (){
let list = await get('http://10.20.159.162:3000/hotcat')
console.log(list)
this.setState({list})
}
render () {
return (
热门分类
{
return
{el.title}
}}
carouselProps={{
style: {
width: '100%',
height: 320,
},
}}
/>
)
}
}
export default HotCate
轮播图数据变更
import React, { Component } from 'react'
import { View, Text, Image } from 'react-native'
import { Carousel } from '@ant-design/react-native'
// 数据请求
import { get } from './../../utils/request'
import styles from './style_index'
// 定义获取到的数据类型
interface Banner {
id: string,
img: string
}
interface Props {
}
interface State {
list: Array
}
class Swiper extends Component< Props, State > {
state: State = {
list: []
}
async componentDidMount () {
let list = await get('http://10.20.159.162:3000/swiper')
this.setState({list})
}
render () {
return (
{
this.state.list.map(item => {
return (
)
})
}
)
}
}
export default Swiper
9. 引入状态管理器
安装mobx状态管理器
yarn add mobx mobx-react
//安装的都是最新版本
旧版本使用方法
// mobx 5
import { observable, action, computed } from 'mobx'
import { get } from './../utils/request'
interface Ilist {
id: string
name: string
img: string
all_click: string
favorites: string
}
class Store {
@observable list: Array = []
@action
async getList () {
let list = await get('http://www.wudaxun.com:3000/swiper')
this.list = list
}
}
export default new Store()
mobx6使用方法
// mobx 6
import { makeAutoObservable } from 'mobx'
import { get } from './../utils/request'
interface Ilist {
id: string
name: string
img: string
all_click: string
favorites: string
}
class Store {
list: Array = []
constructor () {
makeAutoObservable(this)
}
async getList () {
let list = await get('http://www.wudaxun.com:3000/swiper')
this.list = list
}
}
export default new Store()
定义一个store文件夹
//store/index.ts
import { makeAutoObservable, observe } from 'mobx'
import { get } from './../utils/request'
// 接口
interface Ilist {
id: string,
img: string,
name: string,
all_click: string,
favorites: string
}
// 定义状态管理器
class Store {
list: Array = []
constructor (){
makeAutoObservable(this)
}
// 异步请求数据
async getList(){
let list = await get('http://192.168.1.103:3000/swiper')
this.list = list
}
}
const store = new Store()
export default store