React Native学习之路(9) - 注册登录验证的实现 + (用Fetch实现post请求) + (倒计时验证码)+(父子组件通信)+(asyncStorage异步存储) +(TextInput文本输入框)

(1)TextInput文本输入框

TextInput属性
  • (1) keyboardType :设置键盘类型(决定使用哪种键盘)
'email-address' : 邮箱键盘
 'numeric'  :数字键盘
 'phone-pad' :
  • (2) secureTextEntry :如果为true,文本框会遮住之前输入的文字,这样类似密码之类的敏感文字可以更加安全。默认值为false。( secure安全的意思 ) ( entry输入的意思 )
  • (3) placeholder :在文本输入之前提示用户文本框功能,也就是占位文字
  • (4) placeholderTextColor:占位字符串的文本颜色
  • (5) autoFocus:如果为true,在componentDidMount后会获得焦点。默认值为false。
  • (6) selectionColor :设置输入框高亮时的颜色(在iOS上还包括光标)
  • (6) editable:如果值为假,文本是不可编辑,默认值为真7
  • (7) maxLength :限制文本框中最多的字符数。使用这个属性而不用JS逻辑去实现,可以避免闪烁的现象。
  • (8) multiline:如果值为真,文本输入可以输入多行,默认值为假 ( multiline:多线路的 )
  • (9) onFocus :当文本框 (获得)焦点的时候调用此回调函数。
  • (10) onBlur :当文本框 (失去) 焦点的时候调用此回调函数。
  • (11) onChange:当文本框内容变化时调用此回调函数
  • (12) onChangeText:当文本框内容变化时调用此回调函数。改变后的文字内容会作
    为参数传递
 onChangeText={ (text) => {
                            this.setState({
                                phoneNumber: text   
                            })    //当文本框内容发生改变时,将文本框中输入的字符传给state
                        } }
  • (13) onEndEditing :当文本输入结束后调用此回调函数。
  • (14) inlineImageLef :指定一个图片放置在左侧。
  • (15) androidinlineImagePadding :给放置在左侧的图片设置padding样式。
  • (16) autoCapitalize :控制TextInput是否要自动将特定字符切换为大写:
 'characters': 所有的字符。
 'words': 每个单词的第一个字符。
 'sentences': 每句话的第一个字符(默认)。
' none': 不自动切换任何字符为大写。

(2) Fetch中的post请求

(1) JSON.parse() :

解析一个JSON字符串,可选地转换生成的值及其属性,并返回值。( 属性:值)( key:value )

换一种说法是:JSON.parse() 方法解析一个JSON字符串,构造由字符串描述的JavaScript值或对象。可以提供可选的reviver函数以在返回之前对所得到的对象执行变换。

(2) JSON.stringify()

返回与指定值相对应的一个JSON字符串,可选地仅包含某些属性或以用户定义的方式替换属性值。

// 将字符串JSON格式化
JSON.parse(responseData)

// 将JSON数据转化为字符串
JSON.stringify(responseData)
 //更新数据源
    this.setState({
      dataSource:this.state.dataSource.cloneWithRows(JSON.parse(responseData).data)
    });

(3) Post请求

执行POST提交,我们可以将method属性值设置为post,并且在body属性值中设置需要提交的数据。

fetch('https://mywebsite.com/endpoint/', {
  method: 'POST',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    firstParam: 'yourValue',
    secondParam: 'yourOtherValue',
  })
})
-------------------------------------
译注:如果你的服务器无法识别上面POST的数据格式,那么可以尝试传统的form格式,示例如下:
fetch('https://mywebsite.com/endpoint/', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
  },
  body: 'key1=value1&key2=value2'
})
-------------------------------------

POST请求实例:

 fetch("http://rapapi.org/mockjs/22101/api/u/signup",{
            method:'POST',
            headers:{
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            body:JSON.stringify( 'phoneNumber': 'phoneNumber1' )
        }).then( (response) =>   response.json()   )
          .then( (data)=> {
            console.log(data.success)
            if(data && data.success){
                _this.showVerifyCode();
            }else{
                alert('发送验证码失败');
            }
        }).catch( (err) => {
            alert('获取验证码失败');
        })

http://www.cnblogs.com/keyi/p/6721710.html
http://www.jianshu.com/p/7c097051b5dc
http://www.51xuediannao.com/javascript/fetchdyf_fetchxydajaxqqfa__1142.html
http://blog.csdn.net/blueheart20/article/details/45174399
https://zhidao.baidu.com/question/7345375.html
iOS9对https的调整,需要在项目的info.plist添加Key:NSAllowsArbitraryLoads,具体方法看http://www.cnblogs.com/shaoting/p/5148323.html

(这里有个巨坑)http://blog.csdn.net/haoranli/article/details/60960858

   {
              this.state.codeSent
               ? <TouchableNativeFeedback  onPress={ this._submit }>
                      <Text style={ styles.btn}>登陆</Text>
                      </TouchableNativeFeedback>
                :
                  <TouchableNativeFeedback    onPress= { this._sendVerifyCode.bind(this) }>
                        <Text style={ styles.btn}>获取验证码</Text>
                         </TouchableNativeFeedback>
   }
如果不用bind(this)会出现报错

·

(4)验证码倒计时 setInterval() 和 clearInterval()

    
    coutDown() {
        this.setState({
            MainTime:60,
            MainTimeTitle: ''
        });
        this.bb = setInterval( () => {
            var aa = this.state.MainTime - 1;
            if( aa ===0){
                clearInterval( this.bb );
                this.setState({
                    MainTime:'',
                    MainTimeTitle: '重新获取'
                })}else{
                    this.setState({
                        MainTime: aa,
                        MainTimeTitle: ''
                    })
                }
        },1000)
    }
-------------------------------------
 <Text
         onPress={ this.coutDown.bind(this) }
          style={ styles.time}
 >{this.state.MainTime}{this.state.MainTimeTitle}
 </Text>

http://www.jianshu.com/p/819259d09609

(踩坑) :这样写的话会有个警告(如下,如图):


countDown()中的bb方法一直在执行

(解决方法)如下:

Waring: Can only update a mounted or mounting component. 

分析:可以看到在 countdown方法中每秒中调用一次bb方法去递减秒数,
当组件unmounted之后这个timer并没有停止,所以出现了上面的问题。

--------------------------------------------------------
解决方法:
将每次setInterval返回的ID保存起来,在componentWillUnmount方法中clearInterval
--------------------------------------------------------

完整代码:
    //组件将被卸载
    componentWillUnmount() {
        clearInterval(this.state.timeId)
    }
    //倒计时
    coutDown() {
        this.setState({
            MainTime:60,
            MainTimeTitle: ''
        });
        this.bb = setInterval( () => {
            var aa = this.state.MainTime - 1;
            if( aa ===56 ){
                clearInterval( this.bb );
                this.setState({
                    MainTime:'',
                    MainTimeTitle: '重新获取'
                })}else{
                    this.setState({
                        MainTime: aa,
                        MainTimeTitle: ''
                    })
                }
        },1000)
        this.setState({
            timeId: this.bb
        });
    }

http://blog.csdn.net/tujiaw/article/details/58238975

(5) 提交手机号和验证码

(1) 登陆按钮触发事件:

       {
                        this.state.codeSent
                        ? <TouchableNativeFeedback  onPress={ this._submit.bind(this) }>
                            <Text style={ styles.btn}>登陆</Text>
                            </TouchableNativeFeedback>
                        :
                         <TouchableNativeFeedback    onPress= { this._sendVerifyCode.bind(this) }>
                                <Text style={ styles.btn}>获取验证码</Text>
                          </TouchableNativeFeedback>
       }

(2) 登陆函数

_submit(){
        var that =  this;
        var loginPhoneNumber = this.state.phoneNumber;
        var loginVerifyCode = this.state.verifyCode;
        // console.log(loginPhoneNumber);
        // console.log(loginVerifyCode);
        if(!loginPhoneNumber || !loginVerifyCode ){
            return alert( 手机号或者验证码错误 );
        }else{
            fetch("http://rapapi.org/mockjs/22101/api/u/verify",{
                method:'POST',
                header: {
                    'Accept':'application/json',
                    'Content-Type':'application/json'
                },
                body: JSON.stringify({
                    'phoneNumber':'loginPhoneNumber',
                    'verifyCode': 'loginVerifyCode'
                })
            }).then( (response) => response.json() )
              .then((data) => {
                if(data && data.success){
                    // console.log(data)
                    // console.log(data.success)
                    // console.log( MOCK.mock(data) )
                    var data = MOCK.mock(data).data;
                    var stringify = JSON.stringify(data);
                    console.log(stringify);
                    // console.log(data.success)    //值是true
                    // that.props.afterLogin(stringify);
                    // console.log(data)
                    that.props.afterLogin(stringify);

                }else{
                    alert('发送验证码失败22222222222');
                }
              })
              .catch( (err) => {
                  alert('获取验证码失败333333333333');
              })
        }
    }

(3) 子组件传值给父组件

  _afterLogin(user) {
        var that = this;
        // user = JSON.stringify(user);
        AsyncStorage.setItem('user',user)
            .then( ()=> {
                console.log( AsyncStorage.getItem(user) )
                that.setState({
                    logined: false,
                    user: user
                })
                console.log(that.state.logined)
            })
        // this.setState(user)
    }


    render(){
        console.log( this.state.logined );   //true

        if(this.state.logined) {
            return <Login afterLogin={ this._afterLogin.bind(this) }/>;
        };
        return(
        <Go></Go>
        )
    }

这里可以理解为,父组件传递一个方法给子组件,子组件将(值)作为参数返回给父组件,父组件回调
http://blog.csdn.net/hehe0705/article/details/65631768

效果图:


20170724142429.gif

(6) AsyncStorage异步存储

AsyncStorage是一个简单的、异步的、持久化的Key-Value存储系统,它对于App来说是全局性的。它用来代替LocalStorage。

  • AsyncStorage.getItem() :存值


    QQ截图20170724144623.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,099评论 18 139
  • 《裕语言》速成开发手册3.0 官方用户交流:iApp开发交流(1) 239547050iApp开发交流(2) 10...
    叶染柒丶阅读 23,933评论 5 18
  • 《ilua》速成开发手册3.0 官方用户交流:iApp开发交流(1) 239547050iApp开发交流(2) 1...
    叶染柒丶阅读 9,725评论 0 11
  • 点击查看原文 Web SDK 开发手册 SDK 概述 网易云信 SDK 为 Web 应用提供一个完善的 IM 系统...
    layjoy阅读 13,336评论 0 15
  • 今日得到 1.干草堆里找一根不存在的针,成功人士坚持的时间是平常人的五倍多…… 赢家做事情不轻言放弃的能力和习惯都...
    Pheeb阅读 168评论 0 0