首页 > 解决方案 > 在 React Native 中为自定义组件设置多个状态 ID

问题描述

我已经实现了自定义 inputBox 组件。因此,当我第一次使用此组件时,它工作正常,当我在一个页面中多次使用时,数据会预填充到下一个组件。

自定义组件:

import React, { createRef } from 'react';

import {
    View,
    TextInput,
    Alert,
    Text,
    StyleSheet
} from "react-native";

class BoxInput extends React.Component {
    constructor(props) {

        super(props)
        this.state = {
            digit1: '',
            digit2: '',
            digit3: '',
            ...props
        }
        this.digit1Ref = createRef()
        this.digit2Ref = createRef()
        this.digit3Ref = createRef()
    }
    componentDidMount() {
        this.digit1Ref.current.focus()
    }

    componentDidUpdate(prevProps) {
        if (this.state.digit1 && this.state.digit2 &&
            this.state.digit3
           
    }
    saveText(text, key) {
        this.setState({ ...this.state, [key]: text }, () => {
            if (text) {
                key == 'digit1' ? this.digit2Ref.current.focus() : null
                key == 'digit2' ? this.digit3Ref.current.focus() : null
                key == 'digit3'
            }
            const boxInputValue = this.state.digit1 + this.state.digit2 + this.state.digit3
            this.props.onBoxInput(boxInputValue)
        });

    }
    render() {
        return (
            <>
                <TextInput maxLength={1} keyboardType={'numeric'} ref={this.digit1Ref} style={styles.boxStyle} value={this.state.digit1} onChangeText={(text) => this.saveText(text, 'digit1')} />
                <TextInput maxLength={1} keyboardType={'numeric'} ref={this.digit2Ref} style={styles.boxStyle} value={this.state.digit2} onChangeText={(text) => this.saveText(text, 'digit2')} />
                <TextInput maxLength={1} keyboardType={'numeric'} ref={this.digit3Ref} style={styles.boxStyle} value={this.state.digit3} onChangeText={(text) => this.saveText(text, 'digit3')} />
       
            </>
        )
    }
}
const styles = StyleSheet.create({
    boxStyle: {
        marginTop: 20,
        height: 57,
        width: 50,
        borderRadius: 10,
        borderWidth: 1,
        borderColor: '#F1F5F9',
        backgroundColor: '#F1F5F9',
        fontSize: 20,
        lineHeight: 40,
        paddingHorizontal: 15,
        textAlign: 'center'
    }
})
export default BoxInput;

 import React, { createRef } from 'react';
    import styles from './style';
    import {
        View,
        TextInput,
        Alert
    } from "react-native";
    import { connect } from "react-redux";
    import * as Animatable from 'react-native-animatable';
    import BoxInput from "../../../../md-components/atoms/boxinput"
    
    class MPINScreen extends React.Component {
    
        constructor(props) {
            super(props)
            this.state = {
                confirmMpinEnable: true,
                ...props
            }
            this.codes = [{
                value: '+91',
            }]
        }
    
        componentDidUpdate(prevProps) {
            if (this.state.mpinValue.split("").length == 3 &&
                prevProps.success_msg != this.props.success_msg && this.props.success_msg == 'verified') {
                NavigationService.navigate(this.props.navigation, 'MPINVerifyOnboarding')
            }
        }
        handleSubmit = () => {
            if (this.state.mpinValue != this.state.confirmMpinValue) {
                Alert.alert(
                    "Error",
                    "MPIN is not machted",
                    [
                        { text: "OK" }
                    ],
                    { cancelable: false }
                );
            } else {
                this.props.verifyMpin({
                    "mpin": this.state.mpinValue,
                    phoneNumber: this.props.mobileNumber
                })
    
            }
        }
        mpinConfirmation = () => {
            if (this.state.mpinValue.split("").length != 6) {
                Alert.alert(
                    "Error",
                    "Please insert 6 digit mpin",
                    [
                        { text: "OK" }
                    ],
                    { cancelable: false }
                );
    
            }else{
                this.setState({
                    confirmMpinEnable: false,
                });
            }
           
        }
     
        mpinText = (args) => {
            this.setState({
                mpinValue: args,
            });
        }
        confirmMpinText = (args) => {
            this.setState({
                confirmMpinValue: args,
            });
        }
        render() {
            return (
                <>
                    <HeaderComponent backgroundColor="#E5E5E5" showLeftIcon={true} showRightIcon={false} />
                    <View style={styles.container}>
                        <Text style={[styles.textInfo, styles.textTitle]}>We are almost there!</Text>
                        <View style={styles.imageWrapper}>
                            <Animatable.View animation="slideInDown" iterationCount={1} style={styles.centerIconWrap}>
                                <Image style={styles.centerIcon} source={mpin_card} />
                            </Animatable.View>
                        </View>
    
                        {this.state.confirmMpinEnable ? 
                        <Text style={[styles.textInfo]}>Setup your MPIN</Text> : <Text style={[styles.textInfo]}>Confirm your MPIN</Text>
                        }
    
                        {this.state.confirmMpinEnable ?
                            <View style={styles.rowWrap}>
                                <BoxInput id="catFood1" onBoxInput={this.mpinText} />
                            </View>:
                            <View style={styles.rowWrap}>
                                <BoxInput id="catFood2" onBoxInput={this.confirmMpinText} />
                            </View>
                        }
                        <View style={styles.marginBottom}>
                            <Text style={[styles.mpinNote]}>M-PIN is a short 6-digit PIN that you have to set for</Text>
                            <Text style={[styles.mpinNote]}>our mandatory Two-Factor Authentication</Text>
                        </View>
                        <View style={styles.bottomBtnSyle}>
                            <View style={styles.multipleBtnStyle}>
                                <Button onPress={this.handleBack}>{"Back"}</Button>
                            </View>
                            {this.state.confirmMpinEnable ?
                                <View style={styles.multipleBtnStyle}>
                                    <Button onPress={this.mpinConfirmation} >{"Confirm"}</Button>
                                </View> :
                                <View style={styles.multipleBtnStyle}>
                                    <Button onPress={this.handleSubmit} >{"Save & Continue"}</Button>
                                </View>
                            }
                        </View>
    
                    </View>
                </>
            )
        }
    } 
    export default connect(mapStateToProps, mapDispatchToProps)(MPINScreen);

在此处输入图像描述

当我点击确认按钮然后隐藏并显示。但是在第二个组件中,我插入的数据是预先填充的。

在此处输入图像描述

在这个屏幕截图中,数据是预先填充的,但我希望这个为空,因为用户必须再次插入。但它从以前的状态中获取相同的值。我们如何在一页中使用多个时间相同的组件。

标签: reactjsreact-native

解决方案


大概的概念:

创建一个MPINScreen状态属性,每次尝试都会改变(递增)(您可以调用它attempt)并将其作为 prop 传递给BoxInput.

BoxInput创建一个reset函数(将清除文本输入的值并聚焦第一个输入)。componentDidUpdate检查attempt道具是否改变。如果为真 - 将新值保存在BoxInputstate 中并调用“reset”。


推荐阅读