天天看點

React Native 關于箭頭函數、普通函數與點選事件的調用

最近跟着小夥伴寫rn,我負責寫bug,小夥伴負責幫我解bug

React Native 關于箭頭函數、普通函數與點選事件的調用

寫的有些迷糊,尤其是對于箭頭函數與普通函數在點選事件中調用的問題,不知道你是不是也跟我有同樣的疑惑?

箭頭函數

1、箭頭函數一個重要的好處就是對于this對象指向問題,在普通函數中this對象的指向是可變的,是以在普通函數中this對象可能會存在null的情況,但是箭頭函數中this是固定的。

2、this指向定義時所在對象的作用域而不是使用時的。

3、關于使用

//箭頭函數
  press0 = () {
    this.setState({
      data0: "0被點選了"      

調用(以下差別:調用時是否加())

(1)正确:不被立即執行

正确的方式應該不在render的時候立即執行。是以正确調用方法如下,同時,箭頭函數将一個函數指派給press0變量,變量在調用的時候自然不需要加()

Text
         <Text
          style={styles.text}
          onPress={this.press0}
        >{this.state.data0}</Text>      

(2)錯誤:被立即執行

{/*下面的調用方法錯誤,原因:下面的調用方式導緻onPress事件直接被調用press0方法修改了state,

由于state被修改,頁面被重新渲染,再次直接調用press0形成循環

*/}

Text
          style={styles.text}
          onPress={this.press0()}
        >{this.state.data0}</Text>      

普通函數

普通函數的無參與有參的調用方式相同。注意的是有參的函數使用bind方式傳遞參數時this必須在最前面。

調用方式

(1)箭頭方式

() this.press1()}      

(2)bind方式

this.press2.bind(this)}      

無參

//一般方法(無參)
  press1() {
    this.setState({
      data1: "1被點選了"

  press2() {
    this.setState({
      data2: "2被點選了"      

調用

(1)正确:不被立即執行

Text
          style={styles.text}
          onPress={() => this.press1()}
        >{this.state.data1}</Text>

        <Text
          style={styles.text}
          onPress={this.press2.bind(this)}
        >{this.state.data2}</Text>      

(2)錯誤:被立即執行

錯誤原因:同上render渲染被循環調用

Text
          style={styles.text}
          onPress={this.press1()}
        >{this.state.data1}</Text>      

有參

//一般方法(有參)
  press3(x) {
    this.setState({
      data3: x
    })
  };

  press4(x) {
    this.setState({
      data4: x
    })
  };      

調用:

(1)正确:不被立即執行

Text
          style={styles.text}
          onPress={this.press3.bind(this, 2222)}
        >{this.state.data3}</Text>
        <Text
          style={styles.text}
          onPress={()=>this.press4(2222)}
        >{this.state.data4}</Text>      
press5 = (x) {
    this.setState({
      data5: x
    })
  };      
Text
          style={styles.text}
          //onPress={this.press5(2222)}
        >{this.state.data5}</Text>      

整個Demo

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

export default class App extends Component<Props> {

  constructor(props) {
    super(props);
    this.state = {
      data0: '點選0',
      data1: '點選1',
      data2: '點選2',
      data3: '點選3',
      data4: '點選4',
      data5: '點選5',
    }
  };
  //箭頭函數
  press0 = () {
    this.setState({
      data0: "0被點選了"
    })
  };

  //一般方法(無參)
  press1() {
    this.setState({
      data1: "1被點選了"
    })
  };

  press2() {
    this.setState({
      data2: "2被點選了"
    })
  };

  //一般方法(有參)
  press3(x) {
    this.setState({
      data3: x
    })
  };

  press4(x) {
    this.setState({
      data4: x
    })
  };

  press5 = (x) {
    this.setState({
      data5: x
    })
  };



  render() {
    return (
      <View>
        <Text
          style={styles.text}
          onPress={this.press0}
        >{this.state.data0}</Text>
        <Text
          style={styles.text}
          onPress={() this.press1()}
        >{this.state.data1}</Text>

        <Text
          style={styles.text}
          onPress={this.press2.bind(this)}
        >{this.state.data2}</Text>

        <Text
          style={styles.text}
          onPress={this.press3.bind(this, 2222)}
        >{this.state.data3}</Text>


        <Text
          style={styles.text}
          onPress={()=>this.press4(2222)}
        >{this.state.data4}</Text>

        {/*下面的調用方法錯誤,原因:下面的調用方式導緻onpress事件直接被調用press5方法修改了state,
        由于state被修改,頁面被重新渲染,再次直接調用press5形成循環
        */}
        <Text
          style={styles.text}
          //onPress={this.press5(2222)}
        >{this.state.data5}</Text>


      </View>


    );
  }
}

const styles = StyleSheet.create({
  text: {
    backgroundColor: 'red',
    width: 200,
    height: 30,
    marginBottom: 50,
  },
});