TouchableOpacity onPress не работает при попытке установитьState для одного объекта в словаре объектов - PullRequest
0 голосов
/ 13 февраля 2019

Я новичок в реакции-нативный и перепробовал все, что мог придумать.Я искал похожие темы везде.

У меня есть словарь объектов с 4 объектами, на которые я ссылаюсь для использования в ряду из 4 кнопок TouchableOpacity.Каждая кнопка ссылается на свой объект в словаре, и я хочу, чтобы onPress установил состояние нажатой кнопки.Только одна из четырех кнопок должна быть в состоянии выбрать в любой момент времени, и выбранная кнопка должна показать, что это выбранная кнопка.

Всякий раз, когда я нажимаю одну из кнопок, я получаю эту ошибку: setState(...): takes an object of state variables to update or a function which returns an object of state variables.

Я запускаю свой код локально, используя Expo на моем Mac с симулятором iOS.

Компонент строки кнопки My TouchableOpacity

FloorLevel.js

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

const floorLevel = {
    Basement: 'Basement',
    Lower: 'Lower',
    Main: 'Main',
    Upper: 'Upper'
}

export class FloorLevel extends Component {
    constructor(props){
        super(props)
        this.state = {
            floorLevel: {floorLevel}
        }
    }
    render() {
        return (
            <View style={ styles.container }>
                <Text style={{ flexDirection: 'row', justifyContent: 'flex-end', fontWeight: 'bold'}}>Floor Level</Text>
                    <View style={{flexDirection: 'row'}} >
                        <TouchableOpacity testID='floorLevelSelection' onPress={() => this.setState(floorLevel.Basement)}>
                            <Text style={this.state === floorLevel.Basement ? styles.btnActive : styles.btnInactive}>{floorLevel.Basement}</Text>
                        </TouchableOpacity>
                        <TouchableOpacity testID='floorLevelSelection' onPress={() => this.setState(floorLevel.Lower)}>
                            <Text style={this.state === 'Lower' ? styles.btnActive : styles.btnInactive}>{floorLevel.Lower}</Text>
                        </TouchableOpacity>
                        <TouchableOpacity testID='floorLevelSelection' onPress={() => this.setState(floorLevel.Main)}>
                            <Text style={FloorLevel.state === (floorLevel.Main) ? styles.btnActive : styles.btnInactive}>{floorLevel.Main}</Text>
                        </TouchableOpacity>
                        <TouchableOpacity testID='floorLevelSelection' onPress={() => this.setState(floorLevel.Upper)}>
                            <Text style={this.state === (floorLevel.Upper) ? styles.btnActive : styles.btnInactive}>{floorLevel.Upper}</Text>
                        </TouchableOpacity>
                    </View>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        marginTop: 5, 
        textAlign: 'center',
        alignItems: 'center',
        justifyContent: 'center'
    },
    btnActive: {
        borderWidth:1,
        borderColor:'#2196F3',
        height: 30,
        marginTop: 19,
        marginRight: 10,
        alignSelf: 'center',
        alignItems: 'flex-end',
        color: '#2196F3',
        fontSize: 12,
        fontWeight: 'bold',
        textAlign: 'center',
        justifyContent: 'flex-start',
        backgroundColor:'#fff',
        borderRadius:15,
        padding: 6
    },
    btnInactive: {
        borderWidth:1,
        borderColor:'#B5B5B5',
        height: 30,
        marginTop: 19,
        marginRight: 10,
        alignSelf: 'center',
        alignItems: 'flex-end',
        color: '#B5B5B5',
        fontSize: 12,
        fontWeight: 'bold',
        textAlign: 'center',
        justifyContent: 'flex-start',
        backgroundColor:'#fff',
        borderRadius:15,
        padding: 6,

    }
});

Я ожидаю, что состояние будет установлено в состояние выбранной кнопки, и выбранная кнопка должна обновиться с styles.btnInactive до styles.btnActive.

Ответы [ 4 ]

0 голосов
/ 13 февраля 2019

Ваша проблема начинается, когда вы определяете состояние, так как своим кодом вы вытягиваете весь объект и присваиваете ему имя floorlevel.

Если вы хотите изменить состояние при нажатии, а затем сравнитьукажите значение и внесите изменения.приведенный ниже код может помочь немного

Я инициализировал состояние с уровнем (подвал) и собираюсь обновить его, когда onPress () будет вызываться

this.state = {
        level: {floorLevel.basement}
    }

И изменить способ обновлениясостояние

onPress={() => this.setState(level: floorLevel.Lower)

Теперь с другим фрагментом кода должно быть все в порядке (правильно обновите ссылку на состояние)

0 голосов
/ 13 февраля 2019

Функция setState принимает объект в качестве аргумента (состояние вашего компонента является объектом).Поэтому измените код <TouchableOpacity> на onPress={() => this.setState({ floorLevel: floorLevel.Upper })}.

Точно так же вы захотите изменить код тегов <Text>, чтобы иметь действительную проверку стиля, например:

style={this.state.floorLevel === (floorLevel.Upper) ? styles.btnActive : styles.btnInactive}

Кроме того, вам, вероятно, придется изменить конструктор компонента, прямо сейчас он инициализирует floorLevel объектом и при нажатии кнопки floorLevel становится строкой.

0 голосов
/ 13 февраля 2019

: hattip: to @BrunoEduardo за помощь в решении моей проблемы.Вот новый код, следующий за его этапами разрешения.

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

const floorLevel = {
    Basement: 'Basement',
    Lower: 'Lower',
    Main: 'Main',
    Upper: 'Upper'
}

export class FloorLevel extends Component {
    constructor(props){
        super(props)
        this.state = {
            floorLevel: {floorLevel},
        }
    }
    render() {
        return (
            <View style={ styles.container }>
                <Text style={{ flexDirection: 'row', justifyContent: 'flex-end', fontWeight: 'bold'}}>Floor Level</Text>
                    <View style={{flexDirection: 'row'}} >
                        <TouchableOpacity testID='floorLevelSelection' onPress={() => this.setState({ floorLevel: floorLevel.Basement })}>
                            <Text style={this.state.floorLevel === (floorLevel.Basement) ? styles.btnActive : styles.btnInactive}>{floorLevel.Basement}</Text>
                        </TouchableOpacity>
                        <TouchableOpacity testID='floorLevelSelection' onPress={() => this.setState({floorLevel: floorLevel.Lower})}>
                            <Text style={this.state.floorLevel === (floorLevel.Lower) ? styles.btnActive : styles.btnInactive}>{floorLevel.Lower}</Text>
                        </TouchableOpacity>
                        <TouchableOpacity testID='floorLevelSelection' onPress={() => this.setState({floorLevel: floorLevel.Main})}>
                            <Text style={this.state.floorLevel === (floorLevel.Main) ? styles.btnActive : styles.btnInactive}>{floorLevel.Main}</Text>
                        </TouchableOpacity>
                        <TouchableOpacity testID='floorLevelSelection' onPress={() => this.setState({ floorLevel: floorLevel.Upper })}>
                            <Text style={this.state.floorLevel === (floorLevel.Upper) ? styles.btnActive : styles.btnInactive}>{floorLevel.Upper}</Text>
                        </TouchableOpacity>
                    </View>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        marginTop: 5, 
        textAlign: 'center',
        alignItems: 'center',
        justifyContent: 'center'
    },
    btnActive: {
        borderWidth:1,
        borderColor:'#2196F3',
        height: 30,
        marginTop: 19,
        marginRight: 10,
        alignSelf: 'center',
        alignItems: 'flex-end',
        color: '#2196F3',
        fontSize: 12,
        fontWeight: 'bold',
        textAlign: 'center',
        justifyContent: 'flex-start',
        backgroundColor:'#fff',
        borderRadius:15,
        padding: 6
    },
    btnInactive: {
        borderWidth:1,
        borderColor:'#B5B5B5',
        height: 30,
        marginTop: 19,
        marginRight: 10,
        alignSelf: 'center',
        alignItems: 'flex-end',
        color: '#B5B5B5',
        fontSize: 12,
        fontWeight: 'bold',
        textAlign: 'center',
        justifyContent: 'flex-start',
        backgroundColor:'#fff',
        borderRadius:15,
        padding: 6,

    }
});
0 голосов
/ 13 февраля 2019

Отсутствует { } от setState, и значение ключа должно выглядеть следующим образом:

this.setState({floorLevel: floorLevel.Lower})

Но я не уверен на 100%, что вы ожидаете, потому что вы запускаете state.floorLevel с object, тогда, я думаю, вы измените его на string .. не уверен ..

...