React Native开发之快速入门React

前端之家收集整理的这篇文章主要介绍了React Native开发之快速入门React前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

前言

这篇文章,是接着之前的一篇入门文章写的(虽然已经过去大半年了),本文的受众仍然是React小白,熟悉React的同学可以不看了上一篇文章链接

上一篇文章主要介绍了JS的语言基础和React的component生命周期。本文会接着上一篇文章,继续讲解React的基础。

本文的React Native版本是0.0.40,开发IDE是Atom+Nuclide,IDE环境搭建可以参考我的这一篇文章

如果你有足够的时间,非常建议看看React的官方Getting start文档。


准备工作

初始化一个RN的工程,

react-native init ReactBasics

然后,在iOS模拟器(安卓也可以)上运行这个工程。

react-native run-ios

本文所有的代码修改都在index.ios.js中(如果是安卓模拟器,修改index.andorid.js).

默认的ReactBasics代码是这样子的

//...
export default class ReactBasics extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native!
        </Text>
        <Text style={styles.instructions}>
          To get started,edit index.android.js
        </Text>
        <Text style={styles.instructions}>
          Double tap R on your keyboard to reload,{'\n'}
          Shake or press menu button for dev menu
        </Text>
      </View>
    );
  }
}
//...

我们修改为这样

export default class ReactBasics extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Let us learn React.
        </Text>
      </View>
    );
  }
}

然后,运行模拟器

react-native run-ios

看到的如下截图:


React是啥?

React是一个Javascript框架,用来开发web应用。Web应用开发中,比较流行的有三个框架:

从名字上,就能看到React Native是基于React(都是Facebook出品)。React的设计思想是:

  • Declarative(交互式的)。

    应用都是基于状态的,应用会随着数据的变化切换到不同的妆阿嚏。React将这种状态抽象为一个个View,这样状态的改变后,利用React就在不同的View之前切换。这样,让代码更清晰可预测,页方便测试。

  • Component-Based(基于组件)

    把管理状态的View封装成Component,然后再把这些Component组合到一起来实现复杂的UI。

  • Learn Once,Write Anywhere(写一次,到处跑)

    React支持Web开发,Server开发(Node),同样也支持本文提到的App开发(React Native)。


JSX

JSX是JavaScript语言的扩展,它并不改变JS本身语法。使用起来类似XML,React会对JSX的代码进行编译(编译器是babel),生成JavaScript代码,用来描述React中的Element如何渲染。
本文最初的这段代码就是JSX语法。

render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Let us learn React.
        </Text>
      </View>
    );
  }

其中

<Text style={styles.welcome}>
    Let us learn React.
 </Text>

会被编译成

React.createElement(
  Text,{style: styles.welcome},'Let us learn React.' )

注意,使用JSX,一定要在scope中,能够访问到React和对应的Element。比如刚刚的例子,在代码的最上面看到了这样的import

import React,{ Component } from 'react';
import {
  //...
  Text,} from 'react-native';

另外,JSX编译结果可以在线查看在线查看

Tips:JSX本身也是Javascript expression。所以,可以将其赋值给变量,放到if和for中,当然作为参数传入和返回值返回

如果你个Tag是空的,可以用/>进行close。比如

<CustomComponent style={styles.welcome}/>

大小写

JSX对大小写开头是敏感的

  • 小写字母开头会被认为是html内置标签。比如div
  • 大写字母开头会被认为是自己创建或者import的component。

所以,自定义的Components必须是大写字母开头的。

举个例子:
如果上文的Text改成小写,

<text style={styles.welcome}>
    Let us learn React.
 </text>

会被编译成为

React.createElement(
  "text",{style: styles.welcome},'Let us learn React.'
)

React在解析的时候,会认为这和div类似,是html内置标签,引起错误

JS代码

JSX中的JS表达式要用大括号{/*这里是JS代码*/}扩起来,不要加引号,加引号后React会认为它是字符串。

比如,你可以这么写

<Text style={styles.welcome}>
   {"Let" + " us" + " learn" + " react"}
</Text>

点击Save,然后选中模拟器,command+R进行reload,仍然能够正常显示

Children

这是本文最初的代码

<View style={styles.container}>
    <Text style={styles.welcome}>
      Let us learn react
    </Text>
</View>

可以看到,在JSX中可以嵌套Element形成一种层次结构。这种层次结构可以动态生成,比如

render() {
    var textElement = <Text style={styles.welcome}>Let us learn react</Text>
    return (
      <View style={styles.container}>
        {textElement}
      </View>
    );
  }

JSX更多的学习资料,方便想要深入学习的同学:


Element

Element是你在屏幕上想要看到的东西,在React中,一个element就是一个对象。

在React中,element是不可变的。就像电影一样,由一帧一帧组成的,一个element就像电影中的一帧。如果想要用户看到变化,那么就渲染下一帧。

聪明的你可能会问,这样效率不是很低吗?

事实就是,React只会更新变化的那部分,对于不变的试图,是不会重新渲染的。

React强调函数式编程,不可变状态是函数式编程的核心思想之一。不可变状态能够让你的代码更容易编写,测试和维护。一个不可变的函数,在输入一定的时候,输出一定是一样的。


Component

在React native开发中,Component是一个非常重要的概念。它类似iOS中的UIView或者安卓中的View,将视图分成一个个的小部分。

React native中,我们通常采用ES6 class来定义一个Component。

比如上文的代码

export default class ReactBasics extends Component {
    render(){
        @H_72_403@//..
    }
}

其中,render是实际的渲染函数。通常,使用JSX来返回想要看到的视图。

React Native中的Component都是原生的Component,通过JS bridge来调用原生的Component来渲染。

这些Component分为两种:

  1. iOS/Android通用的。比如Navigator,Text,Image等等
  2. 平台独有的,比如NavigatorIOS,ProgressBarAndroid。

State/props

React的Component有两个内置参数对象

  • props,有React自动初始化,包含了传递给一个Component的参数。
  • state,包含的参数对象应当用在render函数中,用作渲染。调用this.setState()会触发上文提到的component重新渲染。

初始化

比如,我们对本文的代码进行修改,新建一个Component

class GreatingComponent extends Component{
  render(){
    return (
      <Text style={styles.welcome}>
          Greating from {this.props.name}
      </Text>
    );
  }
}

这个Component非常简单:读取this.props.name,然后作为Text显示

然后,我们使用这个Component,将ReactBasics修改成如下

export default class ReactBasics extends Component {
  render() {
    return (
      <View style={styles.container}>
        <GreatingComponent name={"Leo"}/>
      </View>
    );
  }
}

然后保存文件,选择模拟器,command+R,重新加载。看到的界面如下:

通过这个例子,如何对Component初始化进行传值已经很清楚了

  • <GreatingComponent name={"Leo"}/>,初始化的时候,通过JSX的参数来传递值
  • GreatingComponent内部,通过this.props.name来访问这个值。

修改视图状态

React中,修改视图状态是通过this.setState触发render重新调用,进而修改视图的状态。

我们继续修改代码添加一个构造函数,对state进行初始化,然后GreatingComponent初始化的时候,读取this.state.name

在最上面的import中,添加一个TouchableOpacity,然后在点击事件中,调用this.setState更新显示文字

export default class ReactBasics extends Component {
  constructor(props) {
   super(props);
   this.state = {name:"Tom"}
  }
  _onPressText(){
    this.setState({name:"Jack"});
  }
  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity onPress={()=>this._onPressText()}>
          <GreatingComponent name={this.state.name}/>
        </TouchableOpacity>
      </View>
    );
  }
}

然后,保存,reload模拟器。点击下文字效果如下。

setState注意事项

//这样并不会触发重新渲染

this.state. name = 'Jack';
  • setState修改可能是异步的。

React有可能会对多个this.setState进行收集,然后一起更新UI。所以,不要直接依赖于上一个状态的结果。
所以,这样是不对的

//此时上一个state可能还没更新
this.setState({
  counter: this.state.counter + this.props.increment,})@H_72_403@;

如果依赖于上一个状态,使用this.setState第二个模式:

@H_72_403@//这里,把上一个state和当前参数作为输入
this.setState(@H_301_601@function(prevState,props) {
  return {
    counter: prevState.counter + props.increment
  };
});
  • setState是增量更新
    比如
export default class ReactBasics extends Component {
  constructor(props) {
   super(props);
   this.state = {firstName:"Tom",lastName:"Huang"}
  }
  _onPressText(){
    this.setState({firstName:"Jack"});
  }
  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity onPress={()=>this._onPressText()}>
          <GreatingComponent name={this.state.firstName +" " + this.state.lastName}/>
        </TouchableOpacity>
      </View>
    );
  }
}

可以看到

this.setState(@H_502_664@{firstName:"Jack"});

效果,只是修改了firstName,lastName仍然保持不变。

Tips:上文onPress中的callBack采用了箭头函数,除了箭头函数,也可以使用function本身传入

export default class ReactBasics extends Component {
  constructor(props) {
   super(props);
   this.state = {firstName:"Tom",lastName:"Huang"}
   this._onPressText = this._onPressText.bind(this);
  }
  _onPressText(){
    this.setState({firstName:"Jack"});
  }
  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity onPress={this._onPressText}>
          <GreatingComponent name={this.state.firstName +" " + this.state.lastName}/>
        </TouchableOpacity>
      </View>
    );

注意这一行

this._onPressText = this._onPressText.bind(this);

因为JS中,class的函数默认没有bound。需要调用bind来把this传入_onPressText


生命周期

关于生命周期,在上一篇文章里已经讲过了。这里再简单带过一笔

使用ES6的class来创建的component生命周期如下:

第一次显示

  • componentWillMount 将要显示
  • componentDidMount 已经显示

调用this.setState

  • shouldComponentUpdate 是否要重新绘制
  • componentWillUpdate 将要重新绘制
  • componentDidUpdate

Component被移除

  • componentWillUnmount

后续

最近一段时间,博客内容会集中在iOS进阶,Swift和React Native三个方面。

原文链接:https://www.f2er.com/react/304991.html

猜你在找的React相关文章