react

用于构建用户界面的JavaScript 库,是三个框架中最简单
的;但是React的生态圈很大:

React:核心
React-Router:路由
Redux:状态管理
React Native:移动App
ReactVR/React360: VR开发

使用React有两种方式:
(1)SCRIPT脚本引入式:可以在任意单一HTML页面使用
(2)React脚手架方式:适合于创建大型Web应用/SPA应用

①下载React CLI脚手架工具
npm  i -g  create-react- app

②进入项目仓库目录,运行React脚手架创建一 个空白项目
create-react-app  项目名

③进入项目根目录,运行此脚手架项目
cd myreactapp03
npm start

NPX工具可以实现的功能:

http://www.ruanyifeng.com/blog/2019/02/npx.html

2.React核心概念之一 一JSX
JavaScript XML:由React定义的融合了XML语法的JS代码一本质还是JS, 只是语法外观上像XML!

浏览器不能直接运行JSX语法!需要使用JSX编译器,转换为浏览器可以执行的JS语法: Babel -第三方提供的JS编译器!

在页面中运行Babel解释器:
<script src= "js/babel.js"> </script>
< scripttype= "text/babel">
//JSX语句
</script>


JSX语法:
①外观像是XML(标签必须闭合,属性值必须用引号,根元素有且只有一个)

②JSX本质不是标签,而是在创建JS标签对象;属性都是JS DOM属性,而不是HTML标签属性,如class必须写作className
③JSX中使用的HTML标签都必须用纯小写形式!自定义标签都必须采用驼峰命名法!

④JSX中若遇到<则会运行HTML解释器;遇到{则会运行JS解释器
⑤JSX中的表达式语法:
{ express },其中的表达式可以是:
变量名、算术运算、比较运算(无错但也无输出)、逻辑运算(无错但也无输出)、三目运算、调用函数、 调用对象的方法、创建新的对象(但可以创建完对象立即调用其成员) 、选择语句(但可以嵌入在匿名自调函数中一唯一的选择语句写法)、循环语句(普通的for不行但可以使用arr.map(fn))?

提示: React JSX中没有类似Angular中的nglf和ngFor指令(React
中没有指令的概念),在JSX中可以在{} 执行函数以返回felse.的
不同结果,也可以在{}执行arr.map( fn )已返回每个元素遍历后返
回的处理结果

3.React核心概念之:二一组件
Component:是一段可复用的页面内容
React中声明组件的语法:

class  MyComponent extends React.Component{
  render(){
    return (0
        //JSX表达式
      )
    }
  }

提示:①React 中的自定义组件必须继承自React.Component

②自定义组件中使用 render0方法返回组件的模板

③自定义组件名首字母必须大写(推荐全驼峰法则); 而JSX中的html标签必须使用纯小写形式

 

提示: React 手册中提供了两种创建自定义组件的方式
(1)function式:简单功能少
function MyButton({ }
(2)class式:复杂功能多
class MyButton extends React.Component{ }


3.组件中的事件绑定

React组件中的事件绑定语法是React所特有的!
①事件名必须onXxx

②事件监听必须是一个function,不能是函数调用
③事件监听函数必须用{ }括起来,不能加双引号
④事件监听函数不能加( )

④事件处理函数默认有一个实参: Event 对象

< button onClick={ this.goBack }>

React中事件处理函数中无法获取this 的三种解决方法:
 方法1:增加匿名函数
    onClick={ ()=>{ this.goBack()}}
 方法2:构造方法中绑定this的指向
    constructor(){
    super( )
    this.goBack = this.goBack.bind(this)
    }

方法3:监听函数赋值为对象的属性,属性值是一个" 箭头函数”
    goBack= (=>{
    //箭头函数中的this 指向不会改变
  }

React中没有v-model/ngModel指令,监听表单元素值改变只能监听onChange


4.组件中的属性/数据绑定 React核心概念之三----state

提示: React 中绑定的数据不能简单的是class属性!其采用的策略类
似于Vuex-数据保存在状态中(state)
①创建数据状态
this.state = { age:20} //只能在构造方法中创建
②绑定数据状态
this.state.age
③修改数据状态
//this.state.age = 30; //无效的修改
this.setState({age: 30})

5.组件中的选择/循环


6.组件间数据传递--React核心概念之四一props

每个组件都可以声明自定义属性(Angular 中称为"输入属性”)
< MyInputGroup
labelTxt=' "xx”inputld="yy"/>
React中组件可以直接使用this.props (Property)读取自己接收到
父组件给与的全部输入属性值(自定义属性无需提前声明)

例如: this.props.labelTxt;子组件也可以通过this.props读取父组件传给自

己的处理函数,用于把子组件中的数据传递给父组件加以使用

React父子组件间数据传递:
(1)父->子:  Props Down
(2)子->父:  Props Up


7.React核心概念之五-- ref
Angular组件脚本查找子组件使用的是@ViewChild
Vue.js/React组件脚本中查找子组件都使用“对象引用”: ref

   <any ref="myChild01>

  this.refs.myChild01...此对象即为组件/元素对象

8.React核心概念之六一受控组件
由React所渲染的所有input. select、 textarea表单元素,都做了特
殊的处理,称为"受控组件”一只要提供 了value但没有提供onChange
事件处理方法,输入项都是只读的;特点如下:
①只要value 属性赋值为一个常量,此值就无法由用户修改
②只要value属性赋值为一个状态变量,但未提供onChange处理方
法,此值就无法由用户修改

③受控组件要求用户必须监听onChange事件,在其中对用户输入进
行检查,合格的数据最终要赋值为state 数据,从而影响输入框的值

 

问题:三大框架是如何提高DOM操作效率的?
Vue.js: Virtual DOM,虚拟DOM
Angular: Dirty Check,脏检查
React: Virtual DOM,虚拟DOM

React中所有的DOM操作底层:都不是直接修改DOM树!

而是React在内存中保存了一份DOM树副本-称为虚
拟DOM树,所有的render操作都是针对虚拟DOM树进
行;只要虚拟DOM树发生改变,就会执行DIFF 算法,把
虚拟DOM与真实DOM之间的不同点绘制到真实DOM

-----用空间(更多的内存)换时间(DOM效率提高)

 

异步加载数据的时间点:
Vue.js: mounted(){ }
Angular: 
ngOnInit(){ }
React: componentDidMount(){}

2.React中组件的生命周期钩子函数
constructor( )
阶段一:加载阶段
componentWilMount( ):组件已创建,即将加载(虚拟DOM与实际不同)
render()

componentDidMount():组件已经加载完成一适合 于加载异步数据
阶段二:更新阶段
componentWillReceiveProps(): (已废弃)组件即将接收到属性数据

shouldComponentUpdate( ):组件应该更新吗?返回true即调用render,否则
不调用
componentWillUpdate( ):组件即将更新
render()
componentDidUpdate():组件更新完成

阶段三:卸载阶段
componentWillUnmount():组件即将卸载,用于清除组件数据,如定时器等

框架中的异步请求:

Vue.js:  Vue-Resource、Axios
Angular: HttpClient
React: 官方未提供

3.React中发起异步请求方法
fetch不是对xhr的封装,而是w3c提供的一种新技术,有望取代xhr
fetch获取异步数据的方法:

fetch(url, {}).then( (res)=>{
return  res.json()
}).then( (data)=>{//data就是响应消息内容
})

示例:创建组件MyProductList,组件加载完成(componentDidMount)
立即获取(fetch)第一页商品数据; 点击“加载更多”再加载下一-页数据
. 商品1
. 商品2
. 商品3

移动端App的三种形式:

(1)NativeApp (原生App):用移动操作系统本身就可以运行的编程语言创建的App,优势:速度快/功能丰富不足: 不跨平台
iOS: ObjectiveC/Swfit; Android: Java/Kotlin

(2)WebApp(H5):用标准Web(HTML/CSS/JS)编写的App,运行于HTML/JS解释器中(WebView对象-浏览器核心),优势:跨平台  不足:运行的效率低/功能欠佳---MintUI

(3)HybridApp(混编App):用标准eb(HTML/CSS/JS)编写的App,再配合.上底层原生代码(OC/Java)做的驱动程序,可以用JS,调用手机底层功能优势: 跨平台/功能比WebApp丰富  不足:效率低---lonic

Vue.js -- MintUI (WebApp)
Angular一lonic (HybridApp)
React一React Native (不用OC/Java的NativeApp)
提示: MintUl/lonic 最终都是HTML/CSS/JS,都要运行在“浏览器/WebView"中; RN代码语法是JS,但是没有HTML/CSS, JS 组件最终会被编译为原生的C/Java代码!一一一RN的运行不依赖与浏览器/WebView

RN应用中也不存在跨域请求问题

4.React生态圈一一一React Native (RN)
英文官网: https://facebook.github.io/react-native/
中文镜像: https://reactnative.cn/

RN:使用JS和React编写NativeApp (原生应用)
RN定义了一整套的React组件库,这些组件库使用JS语言来调
用,运行时会被RN平台编译为OC或者Java代码

注意: RN技术应属于"NativeApp"范畴,不能使用HTML/CSS,
所有的JS组件最终都会被编译为原生代码,直接运行在手机操作系
统上一一无需 WebView核心!

RN开发环境的搭建:脱离浏览器,访问测试需要使用
iOS/Android设备(要么是物理设备、要么是模拟器设备):
https://reactnative.cn/docs/getting-started.html
简化版使用步骤:
(1)下载全局的RN脚手架工具
npm i -g  react- native-cli

 

(2)进入项目仓库,运行RN脚手架创建项目
react- native  init  项目名
(3)进入项目目录,启动该项目
cd  项目名 

npm  start

提示: 上述三步创建的项目是纯JS中,如果想编译为Android/iOS程序
还需要Android/iOS开发软件的支持(Android Studio、Xcode); 编
译后的安装程序:

项目名androidappuildoutputsapkdebugapp-debug.apk

RN项目运行过程:
(1)把项目生成的App安装包安装到手机系统中

直接把app-debug.apk拖到夜神或蓝叠模拟器中就可以完成安装
(2)启动RN服务器端程序
进入RN项目,执行npm  start
启动的是一个Android项目打包和内容发布

注意查看以下服务器所在的IP地址(ipconfig)和端口号(8081)

(3)运行手机中的项目App,会访问RN服务器获取最新的App内容
注意如果提示无法访问需要配置服务器端IP地址和端口号

App客户端:
安装调试用App
启动并配置App,指定服务器端地址和端口
重启App,即可自动连接服务器获取最新内容
后续想刷新记得"摇一 摇> Reload"

ES6箭头函数:有{ }必须自己声明return才有返回值;没有{}相当于有默认
的return语句,下面俩句才是相等的
()=>{
return 1+2
}
()=> 1+2

 

1.RN中常用的组件一重点
注意: RN应用中不允许使用任何HTML标签一底层没有浏览器

(1)Text一一显示一段文字

用法: <Text style={} numberOfLines={3} ellipisizeMode= 'tail' >
内容</Text>

注意: Text的父组件如果是Text则会继承样式,如果是其他组件就
不会样式继承;推荐把View当前Text的父组件

(2)View一一 一块视图区域,类似于HTML中的DIV

用法: <View>... </View>

注意: View默认最大只能铺满手机屏幕,当内容太多超出了屏幕则
无法显示

(3)Button-按钮
用法: <Button title=" 按钮_上的文字”onPress={this.doPress}
color= "red" disabled={true}/>

(4)Image- 图片
用法1:加载手机本地图片
<Image source={require(' ./assets/x.jpg')}/>
无需指定宽和高
用法2:加载远程服务器图片
<Image  source={{uri:'http://xx.com/xjpg'}}
style ={{200,height:100}}
resizeMode= "stretch"

loadingIndicatorSource={require(' ./loading.gif')}/>
必需事先指定需要的宽和高!不指定的话0x0

(5)ImageBackground-背景图片
使用: < ImageBackground source={requirel(..)}>
//将要显示在背景上方的内容
</ImageBackground>

说明:背景图是双标记标签; -般推荐背景图都使用本地图片,但背景图即使是本
地图片,也必须声明width和height!
(6)ScrollView-能滚动的视口
用法: <ScrollView> .. </ScrollView> 
注意:当ScrollView显示的内容超过了屏幕的尺寸,就开始进行水平/竖直的滚动

(7)TextInput--文本输入框
用法:<TextInput  value={this.state.uname}  onChange' Text= {this.doChange}/>
提示: TextInput 属于典型的“受控组件”,想获得用户的输入,必须经过三步:①在构造方法中声明状态数据this state = {uname:"}

②输入框的value绑定到状态数据

③监听输入改变事件,处理方法中修改状态数据

(8)Switch-开关
用法
< Switch   value= {this .state.isOnline}   onValueChange= {this.doChange}/>
提示: Switch 属于典型的"受控组件" ,想获得用户的输入,必须经过三步:

①在构造方法中声明状态数据this state = {isOnline:false} ②输入框的 value绑定到状态
数据③监听输入改变事件,处理方法中修改状态数据

(9)ActivityIndicator--活动提示器, “加载中” 提示符号

用法: <ActivityIndicator size ="large"color="gray"animating= {true}/>
提示:指示器只要“动画停止”,默认就会隐藏
示例:点击按钮“显示/隐藏”加载中指示器

(10)TouchableOpacity--为可触摸组件提供透明效果
用法:
<TouchableOpacity onPress=...}>
  <Any />
</TouchableOpacity>

(3)FlatList--列表组件, 高性能的列表(相较于已废弃的ListView)
用法:< FlatList   data= {this.state.plist}  renderltem= {this._ renderltem}

onEndReached={this.fn}   onEndReachedTreshold={0.1}
ListHeaderComponent={} ListFooterComponent={}
keyExtractor={(item,i)=>i+''}></FlatList>

(4)SectionList--列表组件, 列表项可以进行分组

面向对象扩展知识点:实例属性和静态属性
class Student{
sname='未命名’//实例属性: 每个该类的实例都有一-份
static guoJi='中国’//静态属性: 整个类的所有实例共用一份
}
let s1 = new Student( );
//s1有一个专有的sname
let s2 = new Student(); //s2有一个专有的sname
Student.guoJi = '中华人民共和国'
console.log( Student.guoJi);

"JS远程调试" : console.log 默认在手机的操作系统控制台输出,用
户无法查看到
可以把手机控制台输出使用WebWorker导出到一个浏览器控制台:
摇一摇> Debug JS Remotely

uri和url的关系

2.为RN组件添加样式
(1)行内样式
<Any style={ {color:'red'} }> </Any>
(2)内部样式

let styles = StyleSheet.create({
danger: {
color: 'red'
  }
})
< Any style={styles.danger}> </Any>

 2.RN中的布局

RN中的组件布局采用的类似FlexBox 布局方案,但要比CSS3的
flexbox要简单,相关属性就三个:
①flex:弹性占比: 
number
<Any style= {flex:1}/>
<Any style = {flex:2}}/>
<Any style= {flex:1}/>

②flexDirection: 排列方向: 'column' ,' row'
③alignltems: 子组件的对齐方式:'start', 'center','end'

1.ReactNative阶段项目
实现步骤:
(1)创建空白的RN项目模板,运行服务器端,并用App端来访问
(2)创建项目必需的组件
LoginScreen  盛放登录组件的屏幕
MainScreen  盛放主菜单组件的屏幕
ProductListScreen    商品列表屏幕
ProductDetailScreen   商品列表屏幕

------------------------------------------------------------------------------

(3)声明并注册路由词典,修改App.js

let routes = createStackNavigator({
login: LoginScreen, //第一 个路由即是“首屏内容”
main: MainScreen,
productList: ProductListScreen,
productDetail: ProductDetailScreen,
})
//创建主组件(自带页头),在其中注册路由词典
export default createAppContainer( routes )

此时可以使用客户端进行测试,访问页签中的每个按钮

-----------------------------------------------------------------------------

(4)开始修改登录组件: LoginScreen.js, 添加页面内容

View
>TextInput
> TextInput.secureTextEntry
> Button
> View > Image + Text
>Text


模型数据:this.state = { adminName: ", adminPwd:" }

编写难点:布局、受控组件的输入绑定、fetch 发送POST请求

--------------------------------------------------------------------------------

(5)修改主菜单模板: MainScreen, 添加页面内容


模型数据:

编写难点:布局、标题栏的控制

--------------------------------------------------------------------------------

(6)修改商品列表屏幕模板: ProductListScreen.js, 添加页面内容

模型数据:

编写难点: FlatList、 子组件/父组件数据传递、fetch 和无限滚动

----------------------------------------------------------------------------------
(7)修改商品详情屏幕模板: ProductListScreen.js, 添加页面内容


模型数据:

编写难点:布局、路由传参、自定义轮播组件、动态图片组件的使用

2.RN中的路由和导航
React和React Native官方都没有提供路由模块,可以使用第三方模块:React-Navigation
使用步骤:

①创建页面组件

②定义路由词典

let routes = createStackNavigator({
login: LoginScreen,          //<LoginScreen navigation={}>

main: MainScreen
})

③在根组件中注册路由词典

export default createAppContainer( routes )

④路由跳转

//<LoginScreen navigation={}>
//所有的路由组件,在创建时都被注入一个属性navigation
//组件内部可以使用this.props.navigation访问该属性
this.props.navigation.navigate('....')

⑤跳转传参

页面1:this.props.navigation.navigate('页面2', { pid: 999, uname:" }
页面2: let pid = this.props.navigation.getParam('pid', 默认值)

⑥为每个页面提供头部标题栏内容:
class XxxScreen extends React.Component{
static  navigationOptions = {
title: '页面标题字,
//headerTitle: <Image../>
//headerRight: <Button../>
  }
}

 页面底部固定组件,布局如何实现:

<View style={{flex: 1}}>
< ScrollView>
滚动视图组件特点:会自动占用可用的所有空间
< /ScrollView>
< Button title= "固定在页面底部的按钮"/>
</View>

小技巧:如何获取当前屏幕的尺寸: 
import {Dimensions} from 'react-native' 

屏幕的宽度: Dimensions.get('screen').width
屏幕的高度: Dimensions.get('screen').height


窗口的宽度: Dimensions.get('window').width
窗口的高度: imensions.get("window").height

 

3.如何在RN项目中显示“商品详情”数据? ?
提示:商城中,“商品详情”是由美工/内容编辑人员使用"富客户端编辑器”
编辑生成并保存在数据库中的,其内容就是一-段 HTML,例如: <div> <img
src= "img/xx/123jpg"> </div> <div> <img srC= "img/yy/222jpg"> </div>

RN所有的组件代码最终都要被编译为原生OC/Java代码,不支持任何的HTML标签!

解决方案有两个:

方案1:在RN应用中嵌入一个HTML/CSS解释器(就是浏览器的核心)组件---WebView组件

 
 
 
 
 
 
 
 
 
 
 
 
原文地址:https://www.cnblogs.com/liuqingqing-bloom/p/13406917.html