ReactNative-通過setState控制組件的更新和變化

前言

ReactNative內部分別使用了props, state來區分組件的屬性和狀態。props用來定義組件外部傳進來的屬性, 屬於那種經過外部定義之後, 組件內部就無法改變。而state維持組件內部的狀態更新和變化, 組件渲染出來後響應用戶的一些操作,更新組件的一些狀態。如果組件內部狀態不需要更新,即沒有調用過this.setState, 全部通過props來渲染也是沒問題的, 不過這種情況不常見。本文所介紹的內容就是通過props和state的定義來談談ReactNative的受控組件和非受控組件。

通過this.setState來控制組件的更新和變化,和iOS原生開發中控制組件變化的思想是有很大區別的,iOS中可以直接設置控件的屬性值。初次接觸ReactNative中的這種設計思想還是挺難的。

非受控組件

顧名思義, 非受控組件即組件的狀態改變不受控制.接來下我們以一個簡單TextInput組件代碼來描述。
<TextInput
/>

在這個最簡單的輸入框組件裏,我們並沒有干涉TextInput中的value展示,即用戶通過鍵盤輸入的內容都會展示在上面,但是不能從其他地方改變其內容。

受控組件

上面提到過,既然通過設置input的value屬性, 無法改變輸入框值,那麼我們把它和state結合在一起,再綁定onChange事件,實時更新value值就行了

constructor(props) {
  super(props);
  this.state = {
    value: "",
  }
}

handleChange(e) {
  this.setState({
    value: e.nativeEvent.text
  })
}

render() {
  return (
    <TextInput
      style={styles.style_user_input}
      value={this.state.value}
      onChange={e => this.handleChange(e)}
    />
  );
}

這就是最簡單的受控組件模型, 我們可以通過在onChange的回調裏控制input要顯示的值,
給value賦予this.state.value,通過setState對state的value進行更新,這時會出發render刷新頁面,就會執行到value={this.state.value},TextInput中的內容就得到了更新。

舉兩個簡單的應用場景例子:
1.點擊一個按鈕,TextInput中的內容增加一個特定字符串,比如聊天界面點擊emoji表情,輸入框增加一段“[微笑]”;
2.點擊另一個按鈕,獲取到TextInput中的內容,比如說聊天界面的發送消息。

第一個場景目的是要從外部給TextInput輸入內容,第二個場景是要從外部取到TextInput的內容。這兩個操作都離不開state。

示例

下面展示一個簡單的demo:


完整代碼:

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
   AppRegistry,
  StyleSheet,
  Text,
  Image,
  View,
  TextInput,
  TouchableOpacity,
} from 'react-native';

 
class RNTextIput extends Component {

constructor(props) {
    super(props);
    this.state = {
        value: "",
        gotText: "",
    }
}

  handleChange(e) {
    this.setState({
        value: e.nativeEvent.text
    })
  }

  sendAction() {
    this.setState({
        gotText: this.state.value
    })
  }

  render() {
    return (
         <View style={{backgroundColor:'#f4f4f4',flex:1}}>
          
          <TextInput 
              style={styles.style_user_input}
              placeholder='QQ號/手機號/郵箱'
              numberOfLines={1}
              autoFocus={true}
              underlineColorAndroid={'transparent'} 
              textAlign='center'
              value={this.state.value} 
              onChange={e => this.handleChange(e)}
          />
          <TextInput 
              style={styles.style_pwd_input}
              numberOfLines={1}
              autoFocus={true}
              underlineColorAndroid={'transparent'} 
              textAlign='center'
              value={this.state.gotText} 
          />
          <View style={{height:1,backgroundColor:'#f4f4f4'}} />

          <TouchableOpacity
              onPress={() => {
                this.sendAction();
              }}
            >
              <View  style={styles.style_view_commit} >
                <Text style={{color:'#fff'}}>
                  發送
                </Text>
              </View>
          </TouchableOpacity>

          <TouchableOpacity
              onPress={() => {
                this.setState({value:this.state.value + "文字~"});
              }}
            >
              <View  style={styles.style_view_commit} >
                <Text style={{color:'#fff'}}>
                  手動加入文字
                </Text>
              </View>
          </TouchableOpacity>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  style_image:{
    borderRadius:35,
    height:70,
    width:70,
    marginTop:40,
    alignSelf:'center',
  },
  style_user_input:{  
      backgroundColor:'#fff',
      marginTop:100,
      height:35,
  },
   style_pwd_input:{  
      backgroundColor:'#fff',
      height:35,
      marginTop:10,
  },
   style_view_commit:{  
      marginTop:15,
      marginLeft:10,
      marginRight:10,
      backgroundColor:'#63B8FF',
      height:35,
      borderRadius:5,
      justifyContent: 'center',
      alignItems: 'center',
  },
});

AppRegistry.registerComponent('RNTextIput', () => RNTextIput);

參考:

http://www.cnblogs.com/qingguo/p/5857923.html

http://www.lcode.org/%E3%80%90react-native%E5%BC%80%E5%8F%91%E3%80%91react-native%E6%8E%A7%E4%BB%B6%E4%B9%8Btextinput%E7%BB%84%E4%BB%B6%E8%AE%B2%E8%A7%A3%E4%B8%8Eqq%E7%99%BB%E5%BD%95%E7%95%8C%E9%9D%A2%E5%AE%9E%E7%8E%B011/



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章