React Native基础入门

作者: Lethe35 | 来源:发表于2019-06-04 17:43 被阅读8次

    1.React Native组件

    独立的、可重用的模块。
    有3种方式可以创建组件:1. ES6方式创建;2. ES5方式创建;3.函数式定义无状态组件方式

    // ES6方式创建组件
    type Props = {};
    export default class App extends Component<Props> {
      render() {
        return (
          <View style={styles.container}>
            <Text style={styles.welcome}>Welcome to React Native!</Text>
            <Text style={styles.instructions}>To get started, edit App.js</Text>
            <Text style={styles.instructions}>{instructions}</Text>
          </View>
        );
      }
    }
    
    // ES5方式创建组件
    var App = React.createClass({
      render(){
        return (
          <View style={styles.container}>
            <Text style={styles.welcome}>Welcome to React Native!</Text>
            <Text style={styles.instructions}>To get started, edit App.js</Text>
            <Text style={styles.instructions}>{instructions}</Text>
          </View>
        );
      }
    })
    module.exports = App;
    
    // 无状态组件方式:没有this,没有生命周期函数
    function App(){
      return (
        <View style={styles.container}>
          <Text style={styles.welcome}>Welcome to React Native!</Text>
          <Text style={styles.instructions}>To get started, edit App.js</Text>
          <Text style={styles.instructions}>{instructions}</Text>
        </View>
      );
    }
    module.exports = App;
    
    

    2.React Native组件生命周期

    React Native使用React语法,与React组件拥有一样的生命周期函数,

    分为3种状态:
    Mounting:挂载,已插入真实Dom
    Updating:更新,正在被重新渲染
    Unmounting:卸载,已移出真实Dom
    4个阶段
    创建:只调用getDefaultProps方法
    实例化getInitialStatecomponentWillMountrender(渲染并返回一个虚拟Dom),componentDidMount(根据虚拟Dom对象创建真实Dom,可以在此获取Dom节点)
    更新static getDerivedStateFromProps(props, state)shouldComponentUpdate(nextProps, nextState)render()getSnapshotBeforeUpdate(props, state)componentDidUpdate(preProps, preState, snapshot)
    销毁componentWillUnmount

    3.组件的导入与导出

    // ES6:export导出,import导入
    // 导出
    export default class App extends Component{
      render() {
        return (
          <Text style={styles.welcome}>Welcome to React Native!</Text>
        );
      }
    }
    // 导入
    import App from './App';
    
    // ES5: module.export导出,import导入
    // 导出
    var App = React.createClass({
      render(){
        return (
          <Text style={styles.welcome}>Welcome to React Native!</Text>
        );
      }
    })
    module.exports = App;
    //导入
    import App from './App';
    

    4.props

    React相当于MVC的View层,负责展示,并不涉及到数据,但是组件在使用的过程中有两个属性是和数据有关的:props和state

    props:组件自身的属性,一般用于嵌套的内外层组件中,由父组件传给子组件,负责传递信息,也可以用于属性约束和验证。(props对象中的属性与组件属性一一对应--除this.props.children之外,不要直接修改props属性中的值)
    ...this.props:可以将父组件中传递的全部属性复制给子组件
    this.props.children:组件的所有子节点。它的返回值可以是任意类型的,所以用它来处理一些东西的时候很不方便,好在React的React.Children提供了处理this.props.children的一些方法:React.Children.map()React.Children.forEach()React.Children.count()React.Children.only()React.Children.toArray(),通常与React.cloneElement()结合使用来操作this.props.children。

    属性验证:定义外部组件(父组件)传递的属性值类型是否符合组件定义的类型要求(一般在通用组件定义时使用)

    propsTypes:在React15.5之前可以通过React.PropTypes 进行属性验证,之后我们需要借助prop-types库。

    // 1.引入 prop-types 库
    npm install --save prop-types
    
    // 2.导入prop-types
    import PropTypes from 'prop-types';
    
    // 3.定义子组件
    export default class  PropsTest extends Component{
        // 设置props的默认值
        static defaultProps={ name: 'xiao ming', age: 18, gender: 'man'}
        //约束的关键就是这里在定义属性的时候指定属性的类型,类似安卓private String name;
        static propTypes={
            name: PropTypes.string,
            age: PropTypes.number,
            gender: PropTypes.string.isRequired
        }
        render(){
            //在这里我们使用props中的name属性
              return (
                <Text>
                  {this.props.name}+' age:'+{this.props.age}+'  gender:'+{this.props.gender}
                </Text>
              )
        }
    }
    
    // 4.定义父组件,并在父组件中调用子组件
    export default class  HomePage extends Component{
        render(){
           const params = { name: 'daming', age: 20, gender: 'man' }
           return <PropsText {...params}/>
        }
    }
    

    5.state

    我们使用两种数据来控制一个组件:props和state。props是在父组件中指定,而且一经指定,在被指定的组件的生命周期中则不再改变。 对于需要改变的数据,我们需要使用state。state 的工作原理和 React.js 完全一致。
    一般来说,你需要在 constructor 中初始化state(译注:这是 ES6 的写法,早期的很多 ES5 的例子使用的是 getInitialState 方法来初始化 state,这一做法会逐渐被淘汰),然后在需要修改时调用setState方法,每次调用setState都会重新调用组件render()方法。有几个点需要注意:

    1. 一切界面变化都是状态state变化
    2. state的修改必须通过setState()方法
    3. setState 是一个 merge 合并操作,只修改指定属性,不影响其他属性
    4. setState 是异步操作,修改不会马上生效,要获取到新设置的state属性,需要在setState的回调函数中
    export default class  StateTest extends Component{
        // 设置state的默认值
       state = {
        name: '小红',
        age: 16,
        gender: 'women',
       };
       render(){
             return (
               <Text>
                 {this.state.name}+' age:'+{this.state.age}+'  gender:'+{this.state.gender}
               </Text>
             )
       }
    }
    

    6.ref

    父组件获取子组件的属性

    // 子组件
    export default class  RefTest extends Component{
        // 设置state的默认值
       state = { name: '小白' };
      getName(){
        return this.state.name;
      }
       render(){
             return (
               <Text>
                 哈哈哈
               </Text>
             )
       }
    }
    
    // 父组件
    import RefTest from './RefTest';
    export default class  RefFather extends Component{
       render(){
             return (
                <View>
                   <Text>
                      你好,{this.refTest.getName()}!
                   </Text>
                  <RefTest ref ={refTest => this.refTest=refTest} />
                </View>
             )
       }
    }
    

    7.样式

    在 React Native 中,你并不需要学习什么特殊的语法来定义样式。我们仍然是使用 JavaScript 来写样式。所有的核心组件都接受名为style的属性。这些样式名基本上是遵循了 web 上的 CSS 的命名,只是按照 JS 的语法要求使用了驼峰命名法,例如将background-color改为backgroundColor。
    style属性可以是一个普通的 JavaScript 对象,还可以传入一个数组——在数组中位置居后的样式对象比居前的优先级更高,这样可以间接实现样式的继承。

    定义样式

    1. HTML5以 ‘;’ 结尾
      RN 以 ‘,’ 结尾
    2. HTML5的key、value都不加引号
      RN中属于js对象,key的名字不能出现‘-’,要使用驼峰命名法;如果value为字符串,需要加引号
    3. HTML5中,value如果是数字,需要加单位
      RN中,value是数字不需要加单位

    实际开发中组件的样式会越来越复杂,建议使用StyleSheet.create来集中定义组件的样式。StyleSheet.create的参数是一个对象,对象中的每个属性都是以键值对的形式定义。

    import React, {Component} from 'react';
    import {Platform, StyleSheet, Text, View} from 'react-native';
    
    const instructions = Platform.select({
      ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu',
      android:
        'Double tap R on your keyboard to reload,\n' +
        'Shake or press menu button for dev menu',
    });
    
    type Props = {};
    export default class App extends Component<Props> {
      render() {
        return (
          <View style={styles.container}>
            <Text style={styles.welcome}>Welcome to React Native!</Text>
            <Text style={styles.instructions}>To get started, edit App.js</Text>
            <Text style={styles.instructions}>{instructions}</Text>
          </View>
        );
      }
    }
    
    // StyleSheet.create方式定义样式
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
      },
      welcome: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
      },
      instructions: {
        textAlign: 'center',
        color: '#333333',
        marginBottom: 5,
      },
    });
    
    
    // 通过style直接在组件内定义
    import React, { Component } from 'react';
    import { AppRegistry, View } from 'react-native';
    
    export default class FixedDimensionsBasics extends Component {
      render() {
        return (
          <View>
            <View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
            <View style={{width: 100, height: 100, backgroundColor: 'skyblue'}} />
            <View style={{width: 150, height: 150, backgroundColor: 'steelblue'}} />
          </View>
        );
      }
    }
    

    8.Flexbox布局

    React Native 中使用 flexbox 规则来指定某个组件的子元素的布局。Flexbox 可以在不同屏幕尺寸上提供一致的布局结构。

    1.宽高:组件的高度和宽度决定了其在屏幕上显示的尺寸,也就是大小
    2.弹性(Flex)宽高:在组件样式中使用flex可以使其在可利用的空间中动态地扩张或收缩。一般而言我们会使用flex:1来指定某个组件扩张以撑满所有剩余的空间。如果有多个并列的子组件使用了flex:1,则这些子组件会平分父容器中剩余的空间(前提是其父容器的尺寸不为零,如果父容器既没有固定的width和height,也没有设定flex,则父容器的尺寸为零。其子组件如果使用了flex,也是无法显示的)。如果这些并列的子组件的flex值不一样,则谁的值更大,谁占据剩余空间的比例就更大(即占据剩余空间的比等于并列组件间flex值的比)
    2.无单位:React Native 中的尺寸都是无单位的,表示的是与设备像素密度无关的逻辑像素点,确保了在任何不同dpi的设备上显示都不会发生变化

    React Native 中的 Flexbox 的工作原理和 web 上的 CSS 不同的是:

    1.flexDirection:默认值是column,而不是row,而flex也只能指定一个数字值
    2.alignItems:默认值是stretch,而不是flex-start
    3.flex:只能指定一个参数并且是数字,而Web CSS中可以接受多参数
    4.不支持属性:align-content,flex-basis,order,flex-flow,flex-grow,flex-shrink

    9.网络请求

    很多移动应用都需要从远程地址中获取数据或资源。你可能需要给某个 REST API 发起 POST 请求以提交用户数据,也可能只是需要从某个服务器上获取一些静态内容。
    在React Native中是使用fetch来实现网络请求的。可以参考Fetch 请求文档来查看所有可用的参数。

    发起请求
    要从任意地址获取内容的话,只需简单地将网址作为参数传递给 fetch 方法即可

    fetch('https://mywebsite.com/mydata.json');
    

    Fetch 还有可选的第二个参数,可以用来定制 HTTP 请求一些参数,可以指定 header 参数,或是指定使用 POST 方法,或是提交数据等等:

    fetch('https://mywebsite.com/endpoint/', {
      method: 'POST',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        firstParam: 'yourValue',
        secondParam: 'yourOtherValue',
      }),
    });
    

    提交数据的格式关键取决于 headers 中的Content-Type。Content-Type有很多种,对应 body 的格式也有区别。到底应该采用什么样的Content-Type取决于服务器端,所以请和服务器端的开发人员沟通确定清楚。常用的'Content-Type'除了上面的'application/json',还有传统的网页表单形式,如:

    fetch('https://mywebsite.com/endpoint/', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
      },
      body: 'key1=value1&key2=value2',
    });
    

    使用 Chrome 调试目前无法查看到 React Native 中的网络请求,可以使用第三方的react-native-debugger来进行查看。

    10.基础组件

    View
    在Web开发中,div是最重要的一个元素,是页面布局的基础。在React Native开发中,View组件的作用类似于div,是最基本的组件,被看作是容器组件,不管是显示一个文本还是输入框,都可以把它们放在View组件内部。不论在什么平台上,View 都会直接对应一个平台的原生视图,无论它是 UIView、div还是 android.view.View

    Text
    显示文本内容的组件

    Image
    显示图片内容的组件。用于显示多种不同类型图片的 React 组件,包括网络图片、静态资源、临时的本地图片、以及本地磁盘上的图片(如相册)等

    TextInput
    文本输入框组件

    ScrollView
    可滚动的容器视图。封装了平台的ScrollView(滚动视图)的组件,同时还集成了触摸锁定的“响应者”系统。
    必须要有一个确定的高度,在确保父级容器已经设置了高度情况下,可以通过设置flex: 1以使其自动填充父容器的空余空间

    FlatList组件相比:ScrollView会简单粗暴地把所有子元素一次性全部渲染出来,毫无疑问这会导致一些性能问题,而FlatList会惰性渲染子元素,只在它们将要出现在屏幕中时才开始渲染。除非你要渲染的数据特别少,否则你都应该尽量使用FlatList,此外FlatList还可以方便地渲染行间分隔线,支持多列布局,无限滚动加载等等

    StyleSheet
    提供类似CSS样式表的样式抽象层

    11.交互控件

    常见的跨平台的交互控件
    Button
    一个简单的跨平台的按钮控件。组件的样式是固定的,可以使用TouchableOpacity或是TouchableNativeFeedback组件来定制自己所需要的按钮

    Picker
    在iOS和Android上调用各自原生的选择器控件。

    <Picker
      selectedValue={this.state.language}
      style={{ height: 50, width: 100 }}
      onValueChange={(itemValue, itemIndex) => this.setState({language: itemValue})}>
      <Picker.Item label="Java" value="java" />
      <Picker.Item label="JavaScript" value="js" />
    </Picker>
    

    Slider
    滑动数值选择器

    Switch
    开关,跨平台通用受控组件。通过onValueChange回调来更新value属性以响应用户的操作。如果不更新value属性,组件只会按一开始给定的value值来渲染且保持不变

    12.列表视图

    只会渲染当前屏幕可见的元素(懒加载),这样有利于显示大量的数据
    FlatList
    常用功能

    1.完全跨平台。
    2.支持水平布局模式。
    3.行组件显示或隐藏时可配置回调事件。
    4.支持单独的头部组件。
    5.支持单独的尾部组件。
    6.支持自定义行间分隔线。
    7.支持下拉刷新。
    8.支持上拉加载。
    9.支持跳转到指定行(ScrollToIndex)

    SectionList
    类似FlatList,多了分组显示。
    常用功能

    1.完全跨平台。
    2.行组件显示或隐藏时可配置回调事件。
    3.支持单独的头部组件。
    4.支持单独的尾部组件。
    5.支持自定义行间分隔线。
    6.支持分组的头部组件。
    7.支持分组的分隔线。
    8.支持多种数据源结构
    9.支持下拉刷新。
    10.支持上拉加载。

    相关文章

      网友评论

        本文标题:React Native基础入门

        本文链接:https://www.haomeiwen.com/subject/bbihxctx.html