首页 > 解决方案 > 为什么我的文本输入字段被锁定以进行编辑?

问题描述

我对本机反应仍然很陌生,并且我在使用选择器和文本输入时遇到了问题。

我得到一个汽车列表,当我选择特定汽车时,在下面的字段中设置所选汽车的公里值。

问题是这个字段需要被允许编辑,即用户想改变他能改变的那辆车的公里数。

但是目前我的输入字段被阻止编辑,我制作了一个 gif,显示当我选择一辆车时,我尝试编辑公里,但它不起作用。

当前行为

在我的代码下面,我不知道为什么它不能在snack.io 上运行,所以我把它全部放在这里:

import * as React from 'react';
import {
    Text,
    View,
    ImageBackground,
    Image,
    TextInput,
    Dimensions,
    TouchableOpacity,
    Alert,
    Button,
    Picker,
    Animated,
    Platform,
    TouchableWithoutFeedback,
    StyleSheet
} from 'react-native';
import axios from 'axios';

const { width: WIDTH } = Dimensions.get('window')

export default class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            descViatura: '',
            descViaturaIOS: 'Select the car',
            modalIsVisible: false,
            modalAnimatedValue: new Animated.Value(0),
        };
    }

    componentDidMount() {
        axios
            .get(
                `${'http://www.mocky.io/v2/5d304a3c3200005600204352'}`,
                {
                    headers: {
                        'Content-Type': 'application/json',
                    },
                }
            )
            .then(jsonResponse => {
                this.setState({
                    viaturas: true,
                    dataSource: jsonResponse.data['data'],
                });
            })
            .catch(error => console.log(error));
    }

    onValueChange(value: string, index: string) {
        let kms = this.state.dataSource[index].km_actuais
        let marcaSelecionada = this.state.dataSource[index].marca
        let modeloSelecionado = this.state.dataSource[index].modelo
        let matriculaSelecionada = this.state.dataSource[index].matricula

        let viaturaSelecionada = marcaSelecionada + ' ' + modeloSelecionado + ' ' + matriculaSelecionada

        this.setState({
            descViatura: value,
            km_actuais: kms,
            descViaturaIOS: viaturaSelecionada
        });

    }

    _handlePressOpen = () => {
        if (this.state.modalIsVisible) {
            return;
        }

        this.setState({ modalIsVisible: true }, () => {
            Animated.timing(this.state.modalAnimatedValue, {
                toValue: 1,
                duration: 200,
                useNativeDriver: true,
            }).start();
        });
    };

    _handlePressDone = () => {
        Animated.timing(this.state.modalAnimatedValue, {
            toValue: 0,
            duration: 150,
            useNativeDriver: true,
        }).start(() => {
            this.setState({ modalIsVisible: false });
        });
    };


    render() {
        let list_viaturas = this.state.dataSource;
        if (typeof (list_viaturas) !== undefined) {
            list_viaturas = [list_viaturas][0];
        }

        let km_selected = typeof (this.state.km_actuais) !== 'undefined' ? this.state.km_actuais : 0

        let modalPicker = null
        if (Platform.OS === 'ios') {
            modalPicker = (
                <View style={{
                    flexDirection: 'row',
                    justifyContent: 'center',
                    alignItems: 'center',
                    height: 45,
                    marginTop: 30,
                    width: '90%',
                    backgroundColor: '#ecf0f1',
                    borderWidth: 1,
                }}>
                    <TouchableWithoutFeedback onPress={this._handlePressOpen}>
                        <View
                            style={{
                                alignItems: 'center',
                                width: '100%',
                            }}>
                            <Text style={{ paddingLeft: 15, fontSize: 14 }}>{this.state.descViaturaIOS}</Text>
                        </View>
                    </TouchableWithoutFeedback>
                </View>
            )
        } else {
            modalPicker = (
                null
            )
        }

        _maybeRenderModal = () => {
            if (!this.state.modalIsVisible) {
                return null;
            }

            const { modalAnimatedValue } = this.state;
            const opacity = modalAnimatedValue;
            const translateY = modalAnimatedValue.interpolate({
                inputRange: [0, 1],
                outputRange: [300, 0],
            });

            return (
                <View
                    style={StyleSheet.absoluteFill}
                    pointerEvents={this.state.modalIsVisible ? 'auto' : 'none'}>
                    <TouchableWithoutFeedback onPress={this.props.onCancel}>
                        <Animated.View style={[styles.overlay, { opacity }]} />
                    </TouchableWithoutFeedback>
                    <Animated.View
                        style={{
                            width: '100%',
                            position: 'absolute',
                            bottom: 0,
                            left: 0,
                            transform: [{ translateY }],

                        }}>
                        <View style={styles.toolbar}>
                            <View style={styles.toolbarRight}>
                                <Button title="OK" onPress={this._handlePressDone} />
                            </View>
                        </View>
                        <Picker
                            style={{ width: WIDTH, backgroundColor: '#e1e1e1', top: 0 }}
                            selectedValue={this.state.descViatura}
                            itemStyle={{
                                fontSize: 18,
                                color: '#000',
                            }}
                            onValueChange={this.onValueChange.bind(this)}>
                            {list_viaturas.map((item, key) => {
                                return (
                                    <Picker.Item
                                        label={item.marca + ' ' + ' ' + item.modelo + ' ' + item.matricula}
                                        value={item.id}
                                        key={key}
                                    />
                                );
                            })}
                        </Picker>
                    </Animated.View>
                </View>
            )
        }

        return (
            <View style={styles.container}>
                {modalPicker}
                <View style={styles.inputText2}>
                    <TextInput
                        style={styles.input}
                        value={km_selected}
                        keyboardType={'numeric'}
                        placeholder={"0"}
                        placeholderTextColor={'#000'}
                        underlineColorAndroid='transparent'
                    />
                </View>
                {_maybeRenderModal()}
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#fff',
        padding: 8,
    },
    overlay: {
        ...StyleSheet.absoluteFillObject,
        backgroundColor: 'rgba(0,0,0,0.65)',
    },
    toolbar: {
        width: '100%',
        backgroundColor: '#f1f1f1',
        paddingVertical: 5,
        paddingHorizontal: 15,
    },
    toolbarRight: {
        alignSelf: 'flex-end',
    },
    inputText2: {
        flexDirection: 'row',
        justifyContent: 'center',
        alignItems: 'center',
        height: 45,
        marginTop: 30,
        width: '90%',
        backgroundColor: '#ecf0f1',
        borderWidth: 1,
    },
});

这个gif是加速录制的,但是你可以看到我点击按钮删除了数字,没有任何反应。

加速 gif

标签: javascriptreact-native

解决方案


我相信问题在于您提供的是valueon TextInput.

正如你可以在这里阅读:https ://facebook.github.io/react-native/docs/textinput#value

要为文本输入显示的值。TextInput 是一个受控组件,这意味着如果提供了本机值,将强制匹配此 value 属性。对于大多数用途,这很有效,但在某些情况下,这可能会导致闪烁 - 一个常见原因是通过保持值相同来防止编辑。除了简单地设置相同的值之外,设置 editable={false} 或设置/更新 maxLength 以防止不需要的编辑而不会闪烁。

我无法为您测试,对不起,但请尝试设置editable={true}. 如果它不起作用,请删除value并使用另一种方式通过 JavaScriptvalue从 Picker 中获取并在那里显示它。


推荐阅读