ReactNative学习总结(二)

葛阳
2023-12-01

最近学RN也大概有两个礼拜了。紧跟上篇总结ReactNative一些基础知识再总结下学习RN的笔记。

前言

学习RN,最好的学习办法就是看官方文档,里面有很详细的资料。

环境搭建

开发RN,Atom+Nuclide还是不错的选择。

Atom下载地址
安装Nuclide

$ git clone https://github.com/facebook/nuclide.git
$ cd nuclide
$ npm install     # 安装包依赖
$ apm link

安装好后,就可以进入项目的根目录执行命令

react-native run-ios
//or
react-native run-ios --simulator "iPhone 5s"
//or
react-native run-android

常用的一些细节

  • 回退一个页面
const backAction = NavigationActions.back();
this.props.navigation.dispatch(backAction);
//or
this.props.navigation.pop()
  • ref的使用
    组件之间的通信,可以通过ref的使用来进行通信
<FlatList
  ref={(refs) => {
     this.refreshListView = refs;
  }}
/>
  • DeviceEventEmitter使用

DeviceEventEmitter类似Android里面的EventBus,可以进行广播式通信

使用方式为:
接收广播的界面:

import  {DeviceEventEmitter} from 'react-native';
//...
componentDidMount() {
        this.subscription = DeviceEventEmitter.addListener('Key', this.refreshData.bind(this))
    };
    refreshData(data) {
        this.setState({
            data: data,
        });
    };
    componentWillUnmount() {
        if(this.subscription)
        this.subscription.remove();
    };

发送广播的界面:

import  {DeviceEventEmitter} from 'react-native';
//...
()=>{
     DeviceEventEmitter.emit('Key', {avatar:''})//第二个参数为传递的参数
}
  • 关于使用RN加载图片,部门图片显示不出来问题

RN自带的Image组件是没有缓存的,所以如果在Android的一些内存小的手机上,内存溢出之后就会出现图片显示不出来的问题,可使用react-native-fast-image,使用原生的框架加载图片

如遇到下面这个问题

Native Component component for xxx does not exist

可以尝试在项目的根目录执行下面的命令

react-native link react-native-fast-image
cd android & gradlew clean
cd .. and react-native run-ios/android
  • 上传图片
formData = new FormData();
for(var key in params){//上传文件携带的参数
    formData.append(key,params[key]);
}
for(var index in imgAry){//上传的文件
    let file = {uri: imgAry[index], type: 'multipart/form-data', name: 'image.jpg'};
    formData.append("files",file);
}       
  • moment的使用

主要是一些日期转换的使用,具体使用文档参考moment文档或者参考这篇博客

  • 上拉下拉封装框架

react-native-refresh-list-view

  • TabNavigation的使用

首先TabRouteConfigs

import React from 'react';
import LoveList from "../mine/LoveList";
import FollowList from "../mine/FollowList";

const TabFollowConfigs = {
  LoveList: {
      screen: LoveList,
      navigationOptions:({navigation}) => ({
          tabBarLabel:'最爱',
      }),
  },
  FollowList: {
      screen: FollowList,
      navigationOptions: ({navigation}) => ({
          tabBarLabel: '关注',
      }),
  },
};
module.exports = TabFollowConfigs

然后

const TabNavigatorConfigs = {
    initialRouteName: 'LoveList',
    tabBarComponent: TabBarTop,
    tabBarPosition: 'top',
    swipeEnabled: true,
    lazy: true,
    tabBarOptions: {
      activeTintColor:color.theme,
      inactiveTintColor:'grey',
      scrollEnabled: true,
      indicatorStyle:{
        backgroundColor:color.theme
      },
      style: {
        backgroundColor: 'white'
      },
      tabStyle: {width: tabWidth },
      labelStyle:{
        fontSize:14,
        marginLeft:0,
        marginRight:0
      }
    }
};

如果需要滚动,需要设置tabStyle的tabWidth,否则没有滚动的效果。

最后

const Tab = TabNavigator(TabRouteConfigs, TabNavigatorConfigs);
type props = {}

export default class Article extends Component<props>{
  constructor(props){
    super(props);
  }
  render(){
    return (
      <Tab screenProps={{navigation:this.props.navigation}}/>
    );
  }
}
  • Modal的使用

主要是弹出框的一些布局

<Modal
           animateionType={'fade'}
           transparent={true}
           onrequestclose={() => {console.log("Modal has been closed.")}}
           visible={this.state.modalVisible}
           supportedOrientations={['portrait', 'portrait-upside-down', 'landscape', 'landscape-left', 'landscape-right']}
           onOrientationChange={() => {console.log("Modal has been OrientationChange.")}}>
           <View style={YsListStyle.dialog}>
            //弹出框的一些布局
           </View>
        </Modal>

ART绘制

react-native-art-绘图入门

react-native-art-绘图入门Github

绘制扇形react-art

npm install i react-native-art --save

Surface

  • width : 渲染区域的宽
  • height : 定义渲染区域的高 Shape
  • d : 定义绘制路径
  • stroke : 描边颜色
  • strokeWidth : 描边宽度
  • strokeDash : 定义虚线
  • fill : 填充颜色 Text
  • funt : 字体样式,定义字体、大小、是否加粗 如: bold 35px Heiti SC Path
  • moveTo(x,y) : 移动到坐标(x,y)
  • lineTo(x,y) : 连线到(x,y)
  • arc() : 绘制弧线
  • close() : 封闭空间

mobx的使用

它主要是一个全局状态管理库,主要由Actions,State,Computed Values,Reactions组成。这里举个例子

UserStore.js

import { observable,computed,action } from 'mobx';
import { AsyncStorage } from 'react-native';
import AsyncStorageUtils from '../../utils/AsyncStorageUtils';

export default class UserStore {
    @observable
    userId;
    @observable
    token;
    constructor(){
      AsyncStorageUtils.getItem('user',(value)=>{
        this.updateUser(Json.parse(value));
      });
    }
    @action
    updateUser(user){
      this.userId = user.userId;
      this.token = user.token;
    }

    @computed get isLogin(){
      return (this.userId > 0 && typeof(this.token) != 'undefined'&& this.token != undefined && this.token != '')
    }

}

创建RooterStore.js

import { observable,computed,action } from 'mobx';
import UserStore from './UserStore';

class RootStore {
   constructor(){
     this.userStore = new UserStore();
   }
}

module.exports = new RootStore()

全局注入

//mobx
import { Provider } from 'mobx-react';
import RootStore from './src/mobx/store/RootStore';

const Navigator = StackNavigator({....

const BasicApp = () => {
    return (
      <Provider rootStore={RootStore}>
        <Navigator/>
      </Provider>

    );
}
AppRegistry.registerComponent('MyApplication', () => BasicApp);

然后使用

import {inject, observer} from 'mobx-react';

type props = {} ;
@inject('rootStore')
@observer
export default class Login extends Component<props>{

    changeUser(){
    this.props.rootStore.userStore.updateUser({
        'userId':Math.random()*15,
        'token':''
    });
  }
}

这样就创建完成了。

动画

  • 两个互补动画系统

全局的布局动画LayoutAnimation
精细的交互控制的动画Animated

关于Animated

支持四个可以动画化的组件:View,Text,ImageScrollView,也可以通过Animated.createAnimatedComponent()来封装你自己的组件

第一个动画,透明度动画Animated.timing的使用

import React,{ Component } from 'react';
import {
  StyleSheet,
  Text,
  View,
  Animated,
  Easing
} from 'react-native';

type props = {}

class FadeInView extends Component{
  constructor(props){
    super(props);
    this.state = {
      fadeInOpacity:new Animated.Value(0)
    }
  }
  componentDidMount(){
    Animated.timing(this.state.fadeInOpacity,{
        toValue:1,//目标值
        duration:2500,//动画时间
        easing:Easing.linear//缓动函数
    }).start();

  }
  render(){
    return (
      <Animated.View style={{...this.props.style,opacity:this.state.fadeInOpacity}}>
          {this.props.children}
      </Animated.View>
    );
  }
}

export default class Home extends Component<props>{
  constructor(props){
    super(props);

  }
  render(){
    return (
      <View style={styles.container}>
        <FadeInView style={{width: 250, height: 50, backgroundColor: 'powderblue'}}>
          <Text style={{fontSize: 28, textAlign: 'center', margin: 10}}>Fading in</Text>
        </FadeInView>
      </View>
    );
  }
}

Animated.parallel的使用(同时执行动画)

import React,{ Component } from 'react';
import {
  StyleSheet,
  Text,
  View,
  Animated,
  Easing
} from 'react-native';

type props = {}

class FadeInView extends Component{
  constructor(props){
    super(props);
    this.state = {
      fadeInOpacity:new Animated.Value(0),
      rotation:new Animated.Value(0)
    }
  }
  componentDidMount(){
    var timing = Animated.timing;
    Animated.parallel(['fadeInOpacity','rotation'].map(property => {
      return timing(this.state[property],{
        toValue:1,
        duration:3000,
        easing:Easing.linear
      })
    })).start();
  }
  render(){
    return (
      <Animated.View style={{...this.props.style,opacity:this.state.fadeInOpacity,
        transform:[{
          rotateZ:this.state.rotation.interpolate({
            inputRange:[0,1],
            outputRange:['0deg','360deg']
          })
        }]
      }}>
          {this.props.children}
      </Animated.View>
    );
  }
}

export default class Home extends Component<props>{
  constructor(props){
    super(props);

  }
  render(){
    return (
      <View style={styles.container}>
        <FadeInView style={{width: 250, height: 50, backgroundColor: 'powderblue'}}>
          <View style={{flex:1,justifyContent:'center',alignItems:'center'}}>
            <Text style={{textAlign: 'center',alignSelf:'center',fontSize:26}}>Fading in</Text>
          </View>
        </FadeInView>
      </View>
    );
  }
}

interpolate主要是数组之间的转换

 类似资料: