首页 > 解决方案 > 在模拟器上反应本机 TextInput 值不更新

问题描述

在我的LoginScreen.js

import React, { useState, useReducer, useCallback } from 'react';
import Input from '../components/UI/Input';

const FORM_INPUT_UPDATE = 'FORM_INPUT_UPDATE';

const formReducer = (state, action) => {
    if (action.type === FORM_INPUT_UPDATE) {
        const updatedValues = {
            ...state.inputValues,
            [action.input]: action.value
        };
        const updatedValidities = {
            ...state.inputValidities,
            [action.input]: action.isValid
        };
        let updatedFormIsValid = true;
        for (const key in updatedValidities) {
            updatedFormIsValid = updatedFormIsValid && updatedValidities[key];
        }
        return {
            formIsValid: updatedFormIsValid,
            inputValidities: updatedValidities,
            inputValues: updatedValues
        };
    }
    return state;
};
const LoginScreen = props => {

    const [formState, dispatchFormState] = useReducer(formReducer, {
        inputValues: {
            username:'',
            password:'',
        },
        inputValidities: {
            username: false,
            password: false,
        },
        formIsValid: false
    });

    const inputChangeHandler = useCallback((inputIdentifier, inputValue, inputValidity) => {
        // The last value I entered not showing here if I directly click submit after I finish input
        console.log(inputValue);
        dispatchFormState({
            type: FORM_INPUT_UPDATE,
            value: inputValue,
            isValid: inputValidity,
            input: inputIdentifier
        })
    }, [dispatchFormState]);
    }

    return (
        <Input id='username' keyboardType='default' onInputChange={inputChangeHandler} 
            initialValue=''/>
        <Input id='password' keyboardType='default' onInputChange={inputChangeHandler} 
            initialValue=''/>
        <Button title='Login' onPress={loginHandler} />
    )
}

在我的Input.js,我有

import React, { useReducer, useEffect } from 'react';
import { View, Text, TextInput, StyleSheet, TouchableHighlight } from 'react-native';

const INPUT_CHANGE = 'INPUT_CHANGE';
const INPUT_BLUR = 'INPUT_BLUR';

const inputReducer = (state, action) => {
    switch (action.type) {
        case INPUT_CHANGE:
            return {
                ...state,
                value: action.value,
                isValid: action.isValid,
            }
        case INPUT_BLUR:
            return {
                ...state,
                touched: true,
            }
        default:
            return state;
    }
};

const Input = props => {
    const [inputState, dispatch] = useReducer(inputReducer, {
        value: props.initialValue ? props.initialValue : '',
        isValid: props.initiallyValid,
        touched: false,
    })
    const { onInputChange, id } = props;

    useEffect(() => {
        if (inputState.touched) {
            props.onInputChange(id, inputState.value, inputState.isValid);
        }
    }, [inputState, onInputChange, id]);

    const textChangeHandler = text => {
        let isValid = true;
        if (props.minLength != null && text.length < props.minLength) {
            isValid = false;
        }
        dispatch({ type: INPUT_CHANGE, value: text, isValid: isValid })
    };

    const lostFocusHandler = () => {
        dispatch({ type: INPUT_BLUR, })
    }

    return (
        <TextInput
            {...props}
            value={inputState.value}
            onBlur={lostFocusHandler}
            onChangeText={textChangeHandler}
             /> 
    )

我尝试从模拟器中测试它,并用我的真实键盘输入用户名和密码。当我输入密码后点击登录时,密码的值没有更新,所以我将undefined密码传递给loginHandler函数。顺便说一句,如果我输入密码然后输入用户名,我会得到一个undefined用户名。

我该如何解决这个问题?这会在真正的 iOS 设备上发生吗?谢谢。

标签: react-native

解决方案


推荐阅读