react native props state 網絡請求 native組件等一些基礎知識

时间:2022-09-04 09:36:40

 

> js 6種類型 number string Boolean object function undefined

>給對象添加一個屬性 let a ={} Object.assign(a,{name:’bob’})

>數組的快速拷貝 arrCopy = […array]  使用Array.from(obj) 將一個類似數組的對象轉換成數組

>函數立刻執行的函數寫成((argument)=>{})  異步函數就用promise .then(resolve=>{}) .catch(err=>{}) promise詳情還要看ES6的promise用法

>blurOnsubmit={true} iOS TextInput多行輸入時done不是換行而是收起鍵盤

>檢測一個object是否有某一屬性可以用屬性名 in object 返回true則有該屬性 

>props  是一個對象,是組件用來接收外面傳來的參數, 理論上說props應該是唯一的最標準的父子組件之前通信的一種渠道,組件可以定義初始值自己不能更改props屬性值只能父組件修改傳過來 

默認的 props可以這樣定義 static defaultProps={city:’深圳’}

使用可以 this.props.city 

 通信:父組件通過props傳遞屬性回調給子組件

 this.props.children 如果有一個子節點返回object  有幾個返回array  沒有子節點undefined

>state  組件用來改變自己狀態的屬性 setState({key:value})方法會觸發界面刷新

this.state={name:hahha}

this.setState({name:bob})即可自動觸發刷新機制

 

常用的幾個生命週期方法

  • componentWillMount()  組件開始裝載之前調用 render之前調用業務邏輯可以放在這裡
  • render()  渲染函數返回一個渲染出來的虛擬DOM
  • componentDidMount()   render之後調用這裡開始就可以對組件做各種操作了比如顯示動畫等
  • componentWillUpdate()  組件更新之前調用  每一次屬性更新都會調用 
  • componentDidUpdate()   組件屬性更新之後調用  每一次屬性更新都會調用
  • componentWillUnmount()   組件卸載之前調用可以做一些組件相關的清理操作,比如清空計時器取消網絡請求
  • 建議只在componentWillMount()  componentDidMount()  componentWillReceiveProps()中修改state

>>>組件屬性更改時會調用以下方法,在一次生命週期中可以執行多次

  • componentWillReceiveProps(object nextProps)  已加載組件收到新的參數時調用 this.props被修改或者父組件調用setProps()之後調用通過調用this.setState()來更新組件狀態,舊的屬性還可以通過this.props來獲取,這裡調用更新狀態是安全的,并不會觸發額外的render調用,比如寫一個dialog可以在父組件中設置props  modalVisible = {this.state.modalVisible}  在點擊觸發彈框出現的方法里this.setState({modalVisible:true})  在組件該方法里Animated顯示
  • shouldComponentUpdate(object nextProps, object nextState)  組件判斷是否重新渲染時調用是否需要更新攔截新的propsstate 做出是否要更新的決定,這個方法可以控制渲染提高性能

>>>>>父子組件之間的通信 

都可以通過props props是父子組件通信的最重要甚至是唯一的標準渠道

子組件發生事件通知父組件可以 

 父組件內<Hello onCallback={()=>{this.onChildPress()}}> 

子組件內 <TouchableOpacity onPress={this.props.onCallback}>

父組件發生事件通知子組件 setProps 修改子組件的props即可

 

 

 

ES6 Object.assign() 方法用于对象的合并,将源对象的所有可枚举属性,复制到目标对象,第一个是目标,后面的都是源

var target = { a: 1, b: 1 };

var source1 = { b: 2, c: 2 };

var source2 = { c: 3 };

Object.assign(target, source1, source2);

target // {a:1, b:2, c:3}

var object = Object.assign()  浅拷贝  

等同于扩展运算 var a={q:1} var b ={w:2} let ab = {…a,…b}  let ab = Object.assign({},a,b)

 Object.getOwnPropertyDescriptor()  属性的可枚举性

 

flatList [{},{},{}] info.item

sectionList {key:xxx,datas:[{},{},{}]} info.section.key info.item.xxx

 

react-native-storage 

var storage = new Storage({

size:1000, // 最大容量 

storageBackend:AsyncStorage, // 存儲引擎

 

})

 

// 圖片的幾種resizeMode

cover:     完全填充 分辨率不一樣  圖片會被剪切

contain : 等比縮放 不會變形 可能會露出image底色

stretch :  拉伸填充 會變形 不會切除 

center:     在contain 模式下支持等比放大

// 字符串常見操作

substring() 從開始到結束  包含start 不包含end     start ,end

substr() 從開始到一定長度 end為0則去後面所有的   start , length

indexOf 檢測字符串中某個字符出現的位置  如果沒有出現則返回-1 

  • splice 刪除替換插入

var lang = ["php","java","javascript"]; 

//删除  起始位置長度

var removed = lang.splice(1,1); 

alert(lang); //php,javascript 

alert(removed); //java ,返回删除的项 

//插入 

var insert = lang.splice(0,0,"asp"); //从第0个位置开始插入 

alert(insert); //返回空数组 

alert(lang); //asp,php,javascript 

//替换 

var replace = lang.splice(1,1,"c#","ruby"); //删除一项,插入两项 

alert(lang); //asp,c#,ruby 

alert(replace); //php,返回删除的项 

 

 var arrCopy = arr.slice();  會返回一個原數組的拷貝

 var arr1 = arr.slice(2) 從這個位置以後的所有元素

var arr =[1,2]  var addArr = arr.concat([q,b])  // arr[1,2] addArr[1,2,q,b] 注意: 原數組并沒有變化 會返回一個拼接出來的新數組

var arr = ['A', 'B', 'C', 1, 2, 3];

arr.join('-'); // 'A-B-C-1-2-3'   // join把數組中的元素用一個指定的字符串鏈接起來返回字符串如果arr中的元素不是字符串會自動轉成字符串再連接

 

 

//  native 與原生之間的交互

1>>> native模塊

native端創建一個模塊類實現RCTBridgeMoudle協議  暴露方法RCT_ExportMethod() 

也可以以通知的方式由native端發送  js監聽 var subscription = DeviceEventEmitter.addListener(‘name’,(param)=>{})  native 端發送self.bridge.eventDispatcher sendAppEventWithName:

模塊之間的交互適用於只調用native的一些模塊的方法而不是UI ,比如通知模塊

通信方式:js發起方法的調用傳遞參數給native,native端獲取js傳過來的參數,實現方法,并通過回調與JS通信,傳參數給JS

2>>> native UI組件

native 視圖是通過RCTViewManager的子類創建和操作的

>創建基本的ViewManager的子類

>添加標記宏RCT_EXPORT_MODULE()

>實現-(UIView *)View的方法

 

 

//  react-native  XMLHttpRequest (也就是俗稱的ajax) 

react-native 一般是在componentDidMount()中創建網絡請求,等到請求成功,再用this.setState()將數據成功的渲染到UI

使用xmlHttpRequest發送異步網絡請求

1>>創建網絡請求對象

 let request = new XMLHttpRequest();

2>>request.onreadystatechange = (e) => {

//request.readyState 可能出現5種情況

 if (request.readyState !== 4) {

        return;

      }

      if (request.cancel) {

        return;

      }

 

0 未初始化 xmlHttpRequest已經創建 但是未調用open方法

1 載入 open方法已經在執行 正在使用send向服務器發送請求

2 載入完成 send執行結束 此時已獲取響應的原始數據 但是還不能在客戶端使用

3 交互 解析獲取到的響應數據 根据响应头部的MIME类型把解析到的数据转换成ResponseText,ResponseXML ,ResponseBody能存取的格式的数据。为客户端调用做准备

4 完成 解析結束 直接可以通過XMLHttpRequest響應的屬性,獲取響應的數據

 

request.status  狀態碼

1xx:信息响应类,表示接收到请求并且继续处理 

2xx:处理成功响应类,表示动作被成功接收、理解和接受 

3xx:重定向响应类,为了完成指定的动作,必须接受进一步处理 

4xx:客户端错误,客户请求包含语法错误或者是不能正确执行 

5xx:服务端错误,服务器不能正确执行一个正确的请求

 

2>>創建HTTP請求發送請求

參數有5個 

method : post /get 

url: 請求地址

isAsync : true/false  是否異步發送請求

user : 用戶名

password:密碼

request.open(‘post’,url,true)

 

3>>自定義請求頭

request.setRequestHeader()

如:request.setRequestHeader('device-id', global.deviceInfo.device_id);

    request.setRequestHeader('version-id', global.deviceInfo.version_id);

    request.setRequestHeader('channel-id', '001');

4>> 發送請求

request.send(form)

 

>>>>當然你也可以用fetch(react-native 自帶的網絡請求)

fetch 不是W3C規範 與ajax不同 他的API不是事件機制,而是promise方式處理

fetch(url,obj){ obj是一個對象 包含method headers body mode cache

.then((response)=>{  // 數據解析方式 一般json

return response.json();

})  

.then((responseData)=>{// 獲取到的數據的處理

responseData.obj.XXX

})

.catch((error)=>{ // 異常處理

})

} 

//  比如一個上傳圖片的請求

let formData = new FormData();

let file = {uri:XXX,type:’’,name:a.jpg}

formData.append(‘images’,flle)

fetch(url,{method:’POST’,headers:{},.body:formDate}})

.then((response)=>{response.json()})

.then((responseData)=>{})

.catch((error)=>{})

 

  • body:不可传对象,用JSON.stringify({...})也不可以,在jQuery 中会自动将对象封装成 formData 形式,fetch不会。
  • mode属性控制师傅跨域,其中 same-origin(同源请求,跨域会报error)、no-cors(默认,可以请求其它域的资源,不能访问response内的属性)和 cros(允许跨域,可以获取第三方数据,必要条件是访问的服务允许跨域访问)。
  • 使用 fetch 需要注意浏览器版本,但 React-Native 则不需要考虑

response 对象可以有如下几种解析方式

  • arrayBuffer()
  • json()
  • text()
  • blob()
  • formData()
  1. let formData = new FormData();  
  2. formData.append("name","admin");  
  3. formData.append("password","admin123");  
  4.   
  5. etch(url , {  
  6.  method: 'POST',  
  7.  headers: {},  
  8.  body: formData,  
  9. ).then((response) => {  
  10.  if (response.ok) {  
  11.      return response.json();  
  12.  }  
  13. ).then((json) => {  
  14.  alert(JSON.stringify(json));  
  15. ).catch((error) => {  
  16.  console.error(error);  
  17. );

第三種就是webSocket 這種協議可以在單個TCP鏈接上提供全雙工的通信信道

WebSocket是为解决客户端与服务端实时通信而产生的技术。websocket协议本质上是一个基于tcp的协议,是先通过HTTP/HTTPS协议发起一条特殊的http请求进行握手后创建一个用于交换数据的TCP连接,此后服务端与客户端通过此TCP连接进行实时通信

var ws = new WebSocket('ws://host.com/path');

    ws.onopen = () => {

        // 打开一个连接

        ws.send('something'); // 发送一个消息

    };

    ws.onmessage = (e) => {

        // 接收到了一个消息

        console.log(e.data);

    };

    ws.onerror = (e) => {

        // 发生了一个错误

        console.log(e.message);

    };

    ws.onclose = (e) => {

        // 连接被关闭了

        console.log(e.code, e.reason);

    };

 

 

  • 原生模塊與JS通信  

1>  js主動調用原生, 向原生傳遞消息 ,通過回調native向JS傳參數  RCT_EXPORT_MODULE();

RCT_EXPORT_METHOD(sayHello:(NSString *) msg)   // 定義讓js端調用傳參數的方法,在這裡實現

{

  NSLog(@"打印Hello World%@",msg);

}

@end

// 如果需要native 回調給JS傳遞數據 可以添加一個block 在block里傳遞參數,在js端獲取native傳遞過來的數據

event:(RCTResponseSenderBlock)callback

 NSArray *events = [NSArray arrayWithObjects:@"测试结果",nil];

  callback(@[[NSNull null], events]);

 

在JS端 var myDate = NativeModules.MyDate;

          myDate.printDate(this.state.startDate.getTime(), this.state.endDate.getTime(), (err, result) => {

            alert(result); //  傳遞到native兩個參數  ,JS回調過來一個參數 callback返回的是一個數組,第一個為錯誤信息

      });

2 >  native單向主動調用JS

#import "MyCallBack.h"

#import <React/RCTEventDispatcher.h>

 

@implementation MyCallBack

RCT_EXPORT_MODULE();

@synthesize bridge = _bridge;

RCT_REMAP_METHOD(checkCallBack, str:(NSString *)str)

{

  [self.bridge.eventDispatcher sendAppEventWithName:@"EventCallBack" body:@{@"name": @"sad"}];

}

@end

//  js 端註冊監聽 

 var subscription = NativeAppEventEmitter.addListener(

                'EventCallBack',

                (reminder) => alert(reminder.name)

            );

3 > native導出常量給JS調用

- (NSDictionary *)constantsToExport

{

  return @{ @"firstDayOfTheWeek": @"Monday" };

}

JS端取數據 console.log(MyDate.firstDayOfTheWeek);

 

4> 線程

創建一個MyThread 類 複寫methodQueue方法

@implementation MyThread

RCT_EXPORT_MODULE()

- (dispatch_queue_t)methodQueue

{ return dispatch_get_main_queue();}