React Native touchableopacity onpress无法正常工作

时间:2018-01-31 05:40:12

标签: javascript ios react-native

我是新的回应原生(或任何JS框架),我试图做一个简单的点击游戏,一旦你点击蓝色方块,它随机渲染在不同的位置,然后再次点击,依此类推。到目前为止,这是我的代码:

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

import styles from './src/styles/style';

export default class App extends Component<{}> {

    constructor(props) {
        super();
        this.state = {
        showStartButton: true, // change back to true
        score: 0
    }
}

startGame() {
    this.setState({
       showStartButton: !this.state.showStartButton
    });
    this.renderFirstStage();
}

score() {
    this.setState({
        showStartButton: !this.state.showStartButton,
        score: score+1
    });
}

renderStartButton() {
    return (
        <TouchableOpacity style={styles.startButton} onPress={()=>this.startGame()}>
            <Text style={styles.startButtonText}>START</Text>
        </TouchableOpacity>
    );
}

renderWhiteBox() {
    return (
        <View style={{flex: 1, backgroundColor: 'white'}} />
    );
}

renderBlueBox() {
    return (
        <View style={{flex: 1, backgroundColor: 'blue'}} />
    );
}

renderFirstStage() {
    var blueColNum = Math.floor(Math.random() * 6);
    var blueRowNum = Math.floor(Math.random() * 4);
    var col1 = ['white', 'white', 'white', 'white', 'white', 'white'];
    var col2 = ['white', 'white', 'white', 'white', 'white', 'white'];
    var col3 = ['white', 'white', 'white', 'white', 'white', 'white'];
    var col4 = ['white', 'white', 'white', 'white', 'white', 'white'];

    if (blueRowNum == 0)
        col1[blueColNum] = 'blue';
    else if (blueRowNum == 1)
        col2[blueColNum] = 'blue';
    else if (blueRowNum == 2)
        col3[blueColNum] = 'blue';
    else if (blueRowNum == 3)
        col4[blueColNum] = 'blue';

    return (
        <View style={{flex: 1, flexDirection: 'row'}}>
            <View style={{flex: 1}}>
                <View style={styles.scoreBoard}><Text style={styles.timerText}>Time: {blueRowNum}</Text></View>
                {col1.map(function(el){
                    if (el == 'blue')
                        return (
                            <TouchableOpacity style={{flex: 1, backgroundColor: el}} onPress={()=>this.score()} />
                        );
                    else
                        return (
                            <View style={{flex: 1, backgroundColor: el}} />
                        );
                })}
            </View>
            <View style={{flex: 1}}>
                <View style={{flex: 1, backgroundColor: 'gray'}} />
                {col2.map(function(el){
                    if (el == 'blue')
                        return (
                            <TouchableOpacity style={{flex: 1, backgroundColor: el}} onPress={()=>this.score()}/>
                        );
                    else
                        return (
                            <View style={{flex: 1, backgroundColor: el}} />
                        );
                })}
            </View>
            <View style={{flex: 1}}>
                <View style={{flex: 1, backgroundColor: 'gray'}} />
                {col3.map(function(el){
                    if (el == 'blue')
                        return (
                            <TouchableOpacity style={{flex: 1, backgroundColor: el}} onPress={()=>this.score()} />
                        );
                    else
                        return (
                            <View style={{flex: 1, backgroundColor: el}} />
                        );
                })}
            </View>
            <View style={{flex: 1}}>
                <View style={styles.scoreBoard}><Text style={styles.timerText}>Score: {this.state.score}</Text></View>
                {col4.map(function(el){
                    if (el == 'blue')
                        return (
                            <TouchableOpacity style={{flex: 1, backgroundColor: el}} onPress={()=>this.score()} />
                        );
                    else
                        return (
                            <View style={{flex: 1, backgroundColor: el}} />
                        );
                })}
            </View>
        </View>
    );
}

render() {
    return (
        <View style={styles.container}>
            {this.state.showStartButton ? this.renderStartButton() : null}
                {!this.state.showStartButton ? this.renderFirstStage() : null}
            </View>
        );
    }
}

这就是很多代码,但我想把它全部包含在上下文中。 无论如何,我遇到的问题是我的renderFirstStage()函数。请参阅return语句,我在哪里调用onPress事件处理程序来运行this.score函数?好吧,所以当我运行程序并点击其中一个TouchableOpacities时,我得到一个错误:_this5.score不是函数... _this5.score未定义。 我最好的猜测是,因为我从JSX中的JS代码中调用了onPress = {()=&gt; this.score},而且我不知道如何访问App类中的方法。因此,我认为范围有问题,或者可能不是,我不知道。即使我的预感是正确的,我也不知道如何纠正它。如何从TouchableOpacity组件中调用score方法?我尝试过的任何东西似乎都不适合我...

注意:我在MacBook Pro上运行iPhone 7模拟器。

1 个答案:

答案 0 :(得分:1)

是的,它存在范围问题,您需要在bind

function this constructor上下文
constructor(props) {
    super();
    this.state = {
        showStartButton: true, // change back to true
        score: 0
    }
    this.renderFirstStage = this.renderFirstStage.bind(this);
}

或者您可以使用call立即调用function并将其与this绑定

{!this.state.showStartButton ? this.renderFirstStage.call(this) : null}