React Native初涉

这两天看了下rn文档:https://facebook.github.io/react-native/docs/getting-started.html

做了初步的学习,这里记下一些入门部分的要点。

打怪升级开始--------------------------------------------------------

序:npmV5安装create-react-native-app会报错?

solution:是的,所以官方github上推荐npm切换到v3或v4,或用近期版本的yarn安装:

yarn global add create-react-native-app
create-react-native-app my-app
cd my-app
yarn start

1.ReactNative组件

rn提供的组件分6类:基础展示组件、交互组件、列表组件、针对IOS的组件、针对android的组件、其他组件。

初学者只需要认识前三种。

--基础组件,足以搭建基本的界面UI:

View(相当于div)、Text(相当于p)、Image(相当于img)、TextInput(相当于input)、ScrollView(设定高/宽度后,超出内容可以滚动显示)、StyleSheet(用于创建样式表对象以应用于组件上) 

--交互组件,实现屏幕的点击和手势

Button(应付点击和长按事件,ios和android上样式不一致),RN还提供了自定义类Button交互组件的途径:

TouchableOpacity:用于包裹内容的组件,点击内容会变透明;

TouchableNativeFeedback(android only)

Picker(上下滑动选择器)  Switch(开关按钮)  Slider(类似音量调节的滑动条)  //知道有这几个就行

--列表数据

FlatList:渲染同一类型的简单数据,且不在可视区的不会渲染

SectionList:和FlatList类似,可对数据分组(区),如电话簿按字母对联系人号码分类

2.样式

const styles = StyleSheet.create({
  container: {
    borderRadius: 4,
    borderWidth: 0.5,
  }
});
<View style={styles.container}>
  <Text style={[styles.title, this.props.isActive && styles.activeTitle]} />
</View>

3.布局

RN提供了flexbox的方式实现app界面的布局,但flexbox与css有些区别:

  1.flexDirection属性取值 column || row 且默认值为column(默认排列为竖直方向,基轴为竖直方向)

  2.flex属性只接受一个整数作为值

  3.justifyContent:flex-start || flex-end || center || space-around || space-between || space-evenly

  4.alignItems:flex-start || flex-end || center || stretch (使用stretch时交叉轴方向不能定义长度)

另外,rn提供了Dimensions模块帮我们获取客户端尺寸:

var Dimensions = require('Dimensions');
var { width, height } = Dimensions.get('window');

4.图片

  (1).引用项目源码中的图片

<Image source={require('./test.png')}  />

  编译时RN会以当前js文件为相对路径引用图片。另,如果有test.ios.png和test.android.png两张图,RN会根据平台自动获取对应的一张图。如果有test@2x.png和test@3x.png两张图,RN会根据设备自动获取适当精度的图片。

!注意1:source属性的require(url)里,url推荐使用静态字符串,如:

var icon = this.props.active
  ? require('./my-icon-active.png')
  : require('./my-icon-inactive.png');
<Image source={icon} />;  //不要用模板字符串或变量名构造动态url

!注意2:videos不能使用flex来伸缩,因为非图片资源的尺寸信息不会正确传到source属性中(A caveat is that videos must use absolute positioning instead of flexGrow, since size info is not currently passed for non-image assets. )。如果直接链接到Xcode中或android的资源文件夹中,则没有这个缺陷。

(2).请求网络图片

<Image source={{uri: 'https://facebook.github.io/react/logo-og.png'}}
       style={{width: 400, height: 400}} />

  请求网络图片时候,需要设置尺寸样式

  由于苹果的APP数据传输安全策略,最好使用https协议请求图片;如果图片来源在自己服务器上,可以通过添加白名单规避 add an App Transport Security exception

5.icon在RN中引入icon图标字体要用到插件react-native-vectoricons

6.网络请求

RN提供了fetch方式(也是RN推荐的方式)实现网络请求,fetch只是用promise来实现异步操作,RN里也可以使用async/await语法糖。这里fetch的使用和一般前端的使用一致,可参考MDN文档

RN也实现了内置的XMLHttpRequest API,所以我们也可以直接写ajax,不过这里的ajax并没有实现浏览器的CORS.

RN也支持WebSocket.var ws = new WebSocket('ws://host.com/path');

ws.onopen = () => {
  // connection opened
  ws.send('something'); // send a message
};

ws.onmessage = (e) => {
  // a message was received
  console.log(e.data);
};
ws.οnerrοr=fn
ws.onclose=fn
...

7.平台识别 

RN提供了一个模块,帮助我们识别app所跑的平台是ios还是android:

  (1).Platform模块:

//Platform.OS -- 直接识别平台
import {Platform, StyleSheet} from 'react-native';
const styles = StyleSheet.create({
  height: Platform.OS === 'ios' ? 200 : 100,
});
//Platform.select -- 选取样式
const styles = StyleSheet.create({
  container: {
    flex: 1,
    ...Platform.select({
      ios: {
        backgroundColor: 'red',
      },
      android: {
        backgroundColor: 'blue',
      },
    }),
  },
});
//Platform.select--选取组件
const Component = Platform.select({
  ios: () => require('ComponentIOS'),
  android: () => require('ComponentAndroid'),
})();
<Component />;
//Platform.Version -- android版本
if (Platform.Version === 25) {
  console.log('Running on Nougat!');
}
//ios版本,.Version的结果是一个字符串,表示系统版本号
const majorVersionIOS = parseInt(Platform.Version, 10);
if (majorVersionIOS <= 9) {
  console.log('Work around a change in behavior');
}

(2).组件扩展名检测

当有文件名为Button.ios.js 和 Button.android.js时,const BigButton = require('./BigButton');会直接引入适配平台的那个组件。

8.路由ReactNavigation

过了一遍react-navigation的官网文档,react-navigation是社区针对app常见使用场景开发维护的导航插件。主要提供两个方法:

StackNavigator

export default  HomeScreen = StackNavigator({
  HomeStack: {    //用户自定义的路由名(视图名)
    screen: HomeStack,  //路由名的值是固定格式  {screen:组件名}
  },
  Modal:{screen: Modal}
},
{
    mode: 'modal',  //视图切入时的动画模式,默认自右向左,'modal'则自底向上
    headerMode: 'none',
    initialRouteName: 'HomeStack'
  }
);

  0.StackNavigator生成的路由组件内部实现了类browser的历史记录栈。

  1.用JS对象语法的形式组织视图组件,StackNavigator方法接收两个参数,一个是路由配置对象,第二个可选的功能参数对象。该方法返回一个路由组件。

  2.第一个对象参数的格式是固定的。{自定义路由名:{screen:路由对应的组件名screen component},...rest}

  3.第二个对象参数可以指定初始时显示的视图、当前视图是否隐藏导航头部、视图进入时的动画模式等。

  4.如何实现路由跳转?

  当app中的组件通过StackNavigator组件起来后,可以通过StackNavigator传给screen component的navigation接口实现视图跳转:

 <Button
        onPress={()=>{this.props.navigation.navigate('Modal');}}
        title="Info"
        color="red"
      />

  5.如何实现路由嵌套?

  StackNavigator生成的路由组件可以作为另一个StackNavigator参数中的screen component:

const HomeStack = StackNavigator({
//...
);
export default  HomeScreen = StackNavigator({
  HomeStack: {
    screen: HomeStack,
  },
  //...
},
{
    initialRouteName: 'HomeStack',
  }
);

    在StackNavigator的路由树中可以通过navigation.navigate(routename)自由跳转。

  6.APP中往往有底部的导航标签页,难道也用stacknavigator实现?

  不是。react-navigation提供了另一个专门的方法TabNavigator。用法如StackNavigator.

  7.路由跳转时候带参数?

this.props.navigation.navigate('RouteName',parameterObject): //原视图组件

const {params} = this.props.navigation.navigate.state; //跳转后视图组件

  8.react-navigation自带的头部太丑?

//单纯设置标题
在screen对应的组件,添加静态属性navigationOptions
  static navigationOptions = {
    title: 'Home',
  };
//navigationOptions 也可以是一个函数使用参数
  static navigationOptions = ({ navigation }) => {
    const { params } = navigation.state;
    return {
      title: params ? params.otherParam : 'A Nested Details Screen',
    }
  };
//在该screen组件内更新navigationOptions参数
this.props.navigation.setParams({otherParam: 'Updated!'})
//修改头部样式
headerStyle:包裹头部的div
headerTintColor:返回按钮和标题的颜色
headerTitleStyle:标题样式
//在多个screens中使用通用navigationOptions
const RootStack = StackNavigator(
  {
    Home: {
      screen: HomeScreen,
    },
    Details: {
      screen: DetailsScreen,
    },
  },
  {
    initialRouteName: 'Home',
    /* The header config from HomeScreen is now here */
    navigationOptions: {
      headerStyle: {
        backgroundColor: '#f4511e',
      },
      headerTintColor: '#fff',
      headerTitleStyle: {
        fontWeight: 'bold',
      },
    },
  }
);
//navigationOptions优先级 覆盖
screen component中的navigationOptions会和顶层的StackNavigatior第二个参数的navagationOptions合并
//使用自定义的title
  static navigationOptions = {
    // headerTitle instead of title
    headerTitle: <LogoTitle />,
  };
headerTitle是专门针对StackNavigatior的属性,默认会展示一个Text组件显示title
//添加头部按钮
  static navigationOptions = {
    headerTitle: <LogoTitle />,
    headerRight: (
      <Button
        onPress={() => alert('This is a button!')}
        title="Info"
        color="#fff"
      />
    ),
  };
//通过头部按钮与screen 组件交互
1.static navigationOptions=()=>{params}
2.define method
3.WillMount : setParams
.Button onPress=()=>{param.method}
//修改返回键文本
A组件跳到B组件,在A组件的navigationOptions.headerBackTitle修改文本
//覆盖返回键
navigationOptions.headerLeft

  9.想实现一个全局的模态框?

    最外层navigator包含一个modal组件和一个stack组件,
    在stack组件内部跳转到modal组件
    最外层navigator的option参数添加mode:'modal',headerMode:'none'

TapNavigator

提供顶部或底部导航标签页实现:

const RootStack = TabNavigator({
  Home: {
    screen: HomeScreen,
  },
  //...
},
  {
    mode: 'modal',
    headerMode: 'none',
    initialRouteName: 'Home',
    tabBarOptions: {
      activeTintColor: 'tomato',
      style:{backgroundColor:'#256545'}
    },
    tabBarComponent: TabBarBottom,
    tabBarPosition: 'bottom',
    animationEnabled: false,
    swipeEnabled: false,
  }
);

//待续

7.整合redux

8.开发工具

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值