react native社区项目知识点

react

前言

本来想的上一个React项目做完,从容过完1月迎接新年,IT行业的快节奏真是不容许有这种想法;公司把3月上线的react native项目,时间周期活生生压缩到1月底,真是哭笑不得。这样只能加加班而且保质保量地完成,还是在接口各种报错的前提下利用Mock数据。 言归正传,回到react native项目中来

xcode配置篇

一、iOS APP图标配置

 

二、iOS启动页配置、各种尺寸封面大小

 

 

 

  • 配置完成icon、launchscreen后,要重启xcode再编译方可成功,不然会有缓存
  • Launch Screen苹果官方分辨率大全

TabBar配置篇

一、iPhone X 适配小技巧

  • 应对iphone刘海屏statusbar颜色处理,利用SafeAreaView包裹整个render

    <SafeAreaView style={{backgroundColor:'red'}}></SafeAreaView>

复制代码

  • 上面方法虽然能达到效果,但除了statusbar,整个背景都会被color覆盖,解决办法如下。(附上stackoverflow参考链接)

    <Fragment>

<SafeAreaView style={{ flex:0, backgroundColor: 'red' }} />

<SafeAreaView style={{ flex:1, backgroundColor: 'gray' }}>

<View style={{ flex: 1, backgroundColor: 'white' }} />

</SafeAreaView>

</Fragment>

复制代码

 

二、createBottomTabNavigator 个性化图标

1、所需要显现的效果,中间“检测”图标比较难定位

 

2、代码

    import { createBottomTabNavigator, createAppContainer, createStackNavigator } from 'react-navigation' // 引入依赖

const TabNavigator = createBottomTabNavigator({

Home: {

screen: Home,

navigationOptions:()=>({

title:'首页',

tabBarIcon: ({tintColor,focused}) => (

focused ?

<Image source={require('...')} style={style.nav_icon}/> :

<Image source={require('...')} style={style.nav_icon}/>

)

}),

},

Community: {

screen: Community,

navigationOptions:()=>({

title:'社区',

tabBarIcon: ({tintColor,focused}) => (

focused ?

<Image source={require('...')} style={style.nav_icon}/> :

<Image source={require('...')} style={style.nav_icon}/>

),

tabBarOnPress: ({ navigation, defaultHandler }) => {

/** 触发器

* defaultHandler()、navigation.navigate('Community')

* 两个方法都能实现相同效果,跳转至 Community Component

*/

defaultHandler()

navigation.state.params.triggerAvatar()

}

})

},

Detection: {

screen: Detection,

navigationOptions:()=>({

title:'检测',

tabBarLabel: ({tintColor,focused}) => (

focused ?

<ImageBackground

resizeMode="cover"

source={require('...')}

imageStyle={styles.midIcon_img_wrap}

style={styles.midIcon_wrap}>

<Image source={require('...')} style={styles.midIcon}/>

<Text style={styles.midIcon_word}>检测</Text>

</ImageBackground>

:

<ImageBackground

resizeMode="cover"

source={require('...')}

imageStyle={styles.midIcon_img_wrap}

style={styles.midIcon_wrap}>

<Image source={require('...')} style={styles.midIcon}/>

<Text style={styles.midIcon_word}>检测</Text>

</ImageBackground>

)

}),

},

Recover: {

screen: Recover,

navigationOptions:()=>({

title:'康复',

tabBarIcon: ({tintColor,focused}) => (

focused ?

<Image source={require('...')} style={style.nav_icon}/> :

<Image source={require('...')} style={style.nav_icon}/>

)

}),

},

Me: {

screen: Me,

navigationOptions:()=>({

title:'我的',

tabBarIcon: ({tintColor,focused}) => (

focused ?

<View style={style.nav_icon_wrap}>

<Image source={require('...')} style={style.nav_icon}/>

<MsgSpot/>

</View>

:

<View style={style.nav_icon_wrap}>

<Image source={require('...')} style={style.nav_icon}/>

<MsgSpot/>

</View>

)

})

}

},{

initialRouteName:'Home', // 路由最开始访问

lazy:true, // 是否懒加载

tabBarOptions:{

activeTintColor:'#0168F5',

style:{

borderTopWidth:0,

shadowOpacity: 0.1,

shadowRadius: 5,

shadowColor: '#8B8B8B',

shadowOffset:{ width:0,height:-4 },

paddingHorizontal:16

},

labelStyle:{fontSize:10,position:'relative',top:-2},

tabStyle:{paddingTop:2}

}

})

//StackNavigator

const App = createStackNavigator({

TabNavigator: {screen: TabNavigator, navigationOptions: () => ({gesturesEnabled: true,header: null})},

HomeDetail: {screen: HomeDetail, navigationOptions: () => ({gesturesEnabled: true,header: null})}

})

console.disableYellowBox = true // 屏蔽warning弹窗

export default createAppContainer(App)

复制代码

三、TabNavigator站内消息提示小红点

思路:这种跨组件间事件操作,可以利用Redux实现,但官方给出的是最新版本不会默认集成,那么就自己找方法怎么简单怎么来,首先考虑到的是DeviceEventEmitter

import { DeviceEventEmitter } from 'react-native' // 引入

复制代码

// spot红点事件注册

class MsgSpot extends Component<Props> {

state = { spotShow:false }

componentDidMount(){ // tabbar首次渲染订阅事件

DeviceEventEmitter.addListener('message',param => {

this.setState({spotShow:param.spotShow})

console.log(param)

})

}

render() {

const {spotShow} = this.state

return (

<Fragment>

{spotShow?<View style={[style.redSpot,style.redSpot_nav]}></View>:null}

</Fragment>

)

}

}

复制代码

DeviceEventEmitter.emit('message', {spotShow:true/false}) // 触发事件

复制代码

四、TabNavigator点击触发事情

// 详情看上面tabbar

tabBarOnPress: ({ navigation, defaultHandler }) => {

/** 触发器

* defaultHandler()、navigation.navigate('Community')

* 两个方法都能实现相同效果,跳转至 Community Component

*/

defaultHandler()

navigation.state.params.triggerAvatar()

}

复制代码

五、页面订阅事件

componentDidMount(){

// 订阅生命周期

this._listeners = this.props.navigation.addListener('willFocus', ()=>this.xxx())

}

componentWillUnmount(){

this._listeners.remove() // 移除事件订阅

}

复制代码

react-navigation链接参考

六、导航callback与导航事件注册

// 跳转前页面

startScan = (param) => {} // 1、注册回调

navigate('xxx',{ startScan:this.startScan ,callback:()=>{}})

// 跳转后 xxx 页面

state.params.startScan(param) // 1、触发回调

state.params.callback({}) // 2、触发callback

复制代码

滚动事件、布局篇

一、底部按钮与ScrollView样式

<SafeAreaView style={{flex:1}}>

<ScrollView></ScrollView>

<Text>Button</Text>

</SafeAreaView>

复制代码

二、FlatList 上拉、下拉实现

import {

FlatList,

RefreshControl

} from 'react-native' // 引入

constructor(props){

super(props)

this.dataListFake = [] // 列表数据

this.page = 1 // 页码

this.state = {

dataList : [], // 渲染数据

refresh : true,

pullDown: false,

isLast: false,

loading: false // 正在加载

}

}

componentDidMount() {

this._onRefresh()

}

renderItem = ({item}) => { return () }

renderFooter = () => {

// 显示时机

// 1、刚开始加载、之后,不显示

// 2、下刷新,消失

// 3、上拉加载,动画出现

// 加载完,动画消失;没有数据,显示"暂无更多"

const { pullDown, isLast } = this.state

return (

<View style={[style.footLoad,{paddingBottom:200}]}>

{pullDown?<Image source={require('../../assets/loading.gif')} style={style.footImg}/>:null}

{isLast?<Text style={style.footWord}>暂无更多~</Text>:null}

</View>

)

}

renderEmpty = () => {

return (

<View style={style.renderEmpty}>

<Text>暂无数据</Text>

</View>

)

}

// 下拉刷新

_onRefresh = () => {

const {loading} = this.state

// 是否正在loading

if (!loading){

this.page = 1

this.dataListFake = []

this.setState({refresh:true,isLast:false})

this.dataList(dataListCallBack)

}

function dataListCallBack(){

// Toast.success('刷新成功',800)

}

}

// 上拉加载

_onEndReached = () => {

return false // 没有分页

const {isLast,loading} = this.state

if (!loading){// 是否正在loading

if (isLast){

// Toast.sad('暂无更多数据~')

}else{

this.page++

this.setState({pullDown:true})

this.dataList(dataListCallBack)

}

}

function dataListCallBack(){

// Toast.message(`第${_this.page}页`,null,'center')

}

}

// 网络请求

async dataList(callBack) {

try {

this.setState({loading:true})

...

let data = {

...,

page:this.page,

r:10

}

let data_string = queryString.stringify(data)

let url = ...+'?'+data_string

const response = await axios.get(url)

setTimeout(()=>{this.setState({loading:false})},800) // complete

let code = Number(response.data.code)

let info = response.data.info

if (code===0){

let dataList = response.data.data

this.dataListFake = this.dataListFake.concat(dataList)

this.setState({dataList:this.dataListFake})

}else if (code===9000){ // 根据接口情况而定

setTimeout(()=>{this.setState({isLast:true})},800)

}else{

Toast.sad(info)

}

setTimeout(()=>{

this.setState({

refresh:false,

pullDown:false

}) // 不管数据请求如何,状态归位

},800)

console.log(response.data)

console.log(this.page)

callBack() // 假回调

} catch (error) {

this.setState({refresh:false,pullDown:false,loading:false})

Toast.fail('网络请求异常')

}

}

复制代码

render() {

const { dataList, refresh } = this.state

return (

<SafeAreaView style={[style.container,{flex:1}]}>

<StatusBar barStyle="dark-content"/>

<FlatList

contentContainerStyle={styles.introduction}

data={ dataList }

renderItem={this.renderItem}

ListFooterComponent={this.renderFooter}

ListEmptyComponent={this.renderEmpty}

keyExtractor={this._keyExtractor}

onEndReached={ this._onEndReached }

onEndReachedThreshold={0}

refreshing={refresh}

refreshControl={

<RefreshControl

refreshing={ refresh }

colors={['#ff0000', '#00ff00', '#0000ff']}

progressBackgroundColor={"#ffffff"}

onRefresh={ this._onRefresh }

/>

}

/>

</SafeAreaView>

)

}

复制代码

 

杂文篇

一、条形码扫描 iOS版本

react-native-smart-barcode可以解决大部分问题,集成时因为propTypes的引入没有兼容高版本导致报错,可以去Barcode.js注释掉static propTypes

 

// 同时利用页面订阅,达到每次显示页面重新扫描的目的

this._listeners = this.props.navigation.addListener('didFocus', ()=> this._startScan())

复制代码

二、富文本解析显示 react-native-htmlview

import HTMLView from 'react-native-htmlview' // 引入

复制代码

<HTMLView

value={htmlContent}

addLineBreaks={false} // 去掉每行之间的空格

stylesheet={styles}/>

复制代码

  p:{

color:'#666666',

fontSize:15,

fontWeight:'400',

lineHeight:20,

paddingHorizontal: 0,

marginTop:5,

marginBottom:5

}

复制代码

三、swiper滑动应用 react-native-swiper

四、上传多图

要注意的是传多图时axios需要配置的地方

let config = {headers:{'Content-Type':'multipart/form-data'}}

let formData=new FormData()

xxx.forEach((val,key)=>{

let file = {uri:val.path,type:val.mime,name:val.filename?val.filename:'CAMERA_PHOTO.JPG'}

formData.append(`img${key}`,file)

})

await axios.post(url,formData,config)

复制代码

五、调起打电话

Linking.openURL(`tel:110`)

复制代码

六、react-native-image-crop-picker图片上传遇到的iOS原生问题

1、cd /guyu/ios/podfile

2、cocoapods 安装配置

sudo gem install cocoapods

pod setup

cd ios

pod init

# 3、配置下面文件

# Uncomment the next line to define a global platform for your project

# platform :ios, '9.0'

# 添加至pod文件里面的配置

target 'guyu' do

pod 'RSKImageCropper'

pod 'QBImagePickerController'

end

复制代码

七、axios处理GET时,URL拼接 query-string

query-string更方便拼接url进行Get请求,也方便从url里面解析出键值对来

NPM库

  1. teaset yarn add teaset

  2. react-native-actionsheet yarn add react-native-actionsheet

  3. react-native-fit-image yarn add react-native-fit-image


作者:ClausWong

链接:https://juejin.im/post/5c5402f8f265da2dbd7fd084

来源:掘金

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

以上是 react native社区项目知识点 的全部内容, 来源链接: utcz.com/z/381269.html

回到顶部