如何从ES6中的构造函数获取状态值?

时间:2016-05-06 15:10:41

标签: reactjs react-native ecmascript-6

我正在努力推进ES6语法,但是我在尝试检索状态值时遇到错误。

所以我的问题是:如何获得ES6中的状态值?以下是代码的一部分:

constructor(props) {
    super(props);
    this.state = {
        timeElapsed: null,
        isRunning: false
    }
}

然后当我尝试获得isRunning状态时,它会给我这个错误:无法读取未定义的属性'isRunning'

if (this.state.isRunning) {

    clearInterval(this.interval);
    this.setState({
        isRunning: false
    });
    return

}

有什么想法吗?感谢。

编辑(这是完整的代码):

import React, {Component} from 'react';

import {
    Text,
    View,
    AppRegistry,
    StyleSheet,
    TouchableHighlight
} from 'react-native';

import Moment from 'moment';

import formatTime from 'minutes-seconds-milliseconds';

class StopWatch extends Component {

    constructor(props) {
        super(props);
        this.state = {
            timeElapsed: null,
            isRunning: false
        }
    }

    render() {
        return (
            <View style={styles.container}>
                <View style={styles.header}>
                    <View style={styles.timerWrapper}>
                        <Text style={styles.timer}>{formatTime(this.state.timeElapsed)}</Text>
                    </View>
                    <View style={styles.buttonWrapper}>
                       {this.startStopButton()}
                       {this.lapButton()}
                    </View>
                </View>
                <View style={styles.footer}>
                    <Text>List of laps</Text>
                </View>
            </View>
        )
    }

    startStopButton() {
        var style = this.state.isRunning ? styles.startButton : styles.stopButton;
        return (
            <TouchableHighlight style={[styles.button, style]} onPress={this.handleStartPress} underlayColor="gray">
                <Text>{this.state.isRunning ? 'Stop' : 'Start'}</Text>
            </TouchableHighlight>
        )
    }

    lapButton() {
        return (
            <TouchableHighlight style={[styles.button, styles.lapButton]} onPress={this.lapPress} underlayColor="gray">
                <Text>Lap</Text>
            </TouchableHighlight>
        )
    }

    border(color) {
        return {
            borderColor: color,
            borderWidth: 4
        }
    }

    handleStartPress() {
        console.log('Start was pressed');

        if (this.state.isRunning) {

            clearInterval(this.interval);
            this.setState({
                isRunning: false
            });
            return

        }

        var startTime = new Date();

        this.interval = setInterval(
            ()=>{
                this.setState({
                    timeElapsed: new Date() - startTime
                })
            }, 30
        );

        this.setState({
            isRunning: true
        })

    }

    lapPress() {
        console.log('Lap was pressed');
    }

}

var styles = StyleSheet.create({
    container: { // Main container
        flex: 1,
        alignItems: 'stretch'
    },
    header: { // Yellow
        flex: 2
    },
    footer: { // Blue
        flex: 3
    },
    timerWrapper: {
        flex: 5,
        justifyContent: 'center',
        alignItems: 'center'
    },
    timer: {
        fontSize: 60
    },
    buttonWrapper: {
        flex: 3,
        flexDirection: 'row',
        justifyContent: 'space-around',
        alignItems: 'center'
    },
    button: {
        borderWidth: 2,
        height: 100,
        width: 100,
        borderRadius: 50,
        justifyContent: 'center',
        alignItems: 'center'
    },
    startButton: {
        borderColor: 'red'
    },
    stopButton: {
        borderColor: 'green'
    },
    lapButton: {
        borderColor: 'blue'
    }
});

// AppRegistry.registerComponent('stopWatch', function() {
//     return StopWatch;
// });

AppRegistry.registerComponent('stopwatch', () => StopWatch);

编辑2:

以下是构造函数中有和没有绑定的组合解决方案:

import React, {Component} from 'react';

import {
    Text,
    View,
    AppRegistry,
    StyleSheet,
    TouchableHighlight
} from 'react-native';

import Moment from 'moment';

import formatTime from 'minutes-seconds-milliseconds';

class StopWatch extends Component {

    constructor(props) {
        super(props);

        this.state = {
            timeElapsed: null,
            isRunning: false
        }

        this.startStopButton = this.startStopButton.bind(this)
        this.lapButton = this.lapButton.bind(this)
    }

    render() {
        return (
            <View style={styles.container}>
                <View style={styles.header}>
                    <View style={styles.timerWrapper}>
                        <Text style={styles.timer}>{formatTime(this.state.timeElapsed)}</Text>
                    </View>
                    <View style={styles.buttonWrapper}>
                       {this.startStopButton()}
                       {this.lapButton()}
                    </View>
                </View>
                <View style={styles.footer}>
                    <Text>List of laps</Text>
                </View>
            </View>
        )
    }

    startStopButton() {

        var style = this.state.isRunning ? styles.startButton : styles.stopButton;

        handleStartPress = () => {
            console.log('Start was pressed');

            if (this.state.isRunning) {

                clearInterval(this.interval);
                this.setState({
                    isRunning: false
                });
                return

            }

            var startTime = new Date();

            this.interval = setInterval(
                ()=>{
                    this.setState({
                        timeElapsed: new Date() - startTime
                    })
                }, 30
            );

            this.setState({
                isRunning: true
            })
        }

        return (
            <TouchableHighlight style={[styles.button, style]} onPress={handleStartPress} underlayColor="gray">
                <Text>{this.state.isRunning ? 'Stop' : 'Start'}</Text>
            </TouchableHighlight>
        )

    }

    lapButton() {

        handleLapPress = () => {
            console.log('Lap was pressed');
        }

        return (
            <TouchableHighlight style={[styles.button, styles.lapButton]} onPress={handleLapPress} underlayColor="gray">
                <Text>Lap</Text>
            </TouchableHighlight>
        )

    }

    border(color) {

        return {
            borderColor: color,
            borderWidth: 4
        }

    }

}

var styles = StyleSheet.create({
    container: { // Main container
        flex: 1,
        alignItems: 'stretch'
    },
    header: { // Yellow
        flex: 2
    },
    footer: { // Blue
        flex: 3
    },
    timerWrapper: {
        flex: 5,
        justifyContent: 'center',
        alignItems: 'center'
    },
    timer: {
        fontSize: 60
    },
    buttonWrapper: {
        flex: 3,
        flexDirection: 'row',
        justifyContent: 'space-around',
        alignItems: 'center'
    },
    button: {
        borderWidth: 2,
        height: 100,
        width: 100,
        borderRadius: 50,
        justifyContent: 'center',
        alignItems: 'center'
    },
    startButton: {
        borderColor: 'red'
    },
    stopButton: {
        borderColor: 'green'
    },
    lapButton: {
        borderColor: 'blue'
    }
});

AppRegistry.registerComponent('stopwatch', () => StopWatch);

2 个答案:

答案 0 :(得分:3)

您需要将类方法绑定到正确的this。请参阅有关使用ES6课程的facebook文档:https://facebook.github.io/react/docs/reusable-components.html#es6-classes

要修复错误,请在类构造函数中绑定方法:

class StopWatch extends Component {

constructor(props) {
    super(props);

    this.state = {
        timeElapsed: null,
        isRunning: false
    }

    this.startStopButton= this.startStopButton.bind(this)
    this.lapButton = this.lapButton.bind(this)
    this.handleStartPress = this.handleStartPress.bind(this)
    this.handleLap = this.handleLap.bind(this)
}

render() {
    return (
        <View style={styles.container}>
            <View style={styles.header}>
                <View style={styles.timerWrapper}>
                    <Text style={styles.timer}>{formatTime(this.state.timeElapsed)}</Text>
                </View>
                <View style={styles.buttonWrapper}>
                   {this.startStopButton()}
                   {this.lapButton()}
                </View>
            </View>
            <View style={styles.footer}>
                <Text>List of laps</Text>
            </View>
        </View>
    )
}

startStopButton() {
    var style = this.state.isRunning ? styles.startButton : styles.stopButton;
    return (
        <TouchableHighlight style={[styles.button, style]} onPress={this.handleStartPress} underlayColor="gray">
            <Text>{this.state.isRunning ? 'Stop' : 'Start'}</Text>
        </TouchableHighlight>
    )
}

lapButton() {
    return (
        <TouchableHighlight style={[styles.button, styles.lapButton]} onPress={this.lapPress} underlayColor="gray">
            <Text>Lap</Text>
        </TouchableHighlight>
    )
}

border(color) {
    return {
        borderColor: color,
        borderWidth: 4
    }
}

handleStartPress() {
    console.log('Start was pressed');

    if (this.state.isRunning) {

        clearInterval(this.interval);
        this.setState({
            isRunning: false
        });
        return

    }

    var startTime = new Date();

    this.interval = setInterval(
        ()=>{
            this.setState({
                timeElapsed: new Date() - startTime
            })
        }, 30
    );

    this.setState({
        isRunning: true
    })

}

lapPress() {
    console.log('Lap was pressed');
}

}

抱歉格式错误

答案 1 :(得分:2)

这与ES6无关,这是Javascript工作方式的固有难题。

您的错误在这里:

  

onPress = {this.lapPress}

您正在考虑这意味着&#34;当按下按钮时,调用我的组件上的方法lapPress&#34;。它没有。这意味着&#34;当按下按钮时,从我的组件调用方法lapPress,使用恰好被设置为&#34;的任何this

有几种方法可以正确地将其绑定到它的方法,但最简单的(在ES6中)可能是

  

onPress = {()=&gt; this.lapPress()}