React Native jsx条件渲染不会在状态更改时更新

kqhtkvqz  于 2023-10-22  发布在  React
关注(0)|答案(1)|浏览(156)

我想在AuthForm组件中有条件地呈现jsx,但我在“isPasscodeEntry”场景中遇到了麻烦。
我的AuthForm组件根据isLogin、isForgot和isPasscodeEntry的状态有条件地呈现输入表单。
AuthForm在AuthContent中导入和呈现。
AuthContent在我的LoginScreen组件中根据isLogin、isForgot和isPasscodeEntry的状态有条件地呈现。
isLogin =登录/!isLogin =注册/ isForgot =输入电子邮件>获取密码电子邮件/ isPasscodeEntry =输入密码
在LoginScreen中,我在控制台记录isPasscodeEntry的状态,当我按下“重置密码”时,它会变为true,但isPasscodeEntry jsx不会被渲染。
总结如下:
当isForgot为true时(密码重置流程):
如果isForgot为true(密码重置流程),则当按下“重置密码”按钮时,将有条件地呈现isPasscodeEntry JSX。
当按下“重置密码”按钮时(isForgot为true),它将调用setIsPasscodeEntry()。
当isForgot为false时(登录或注册流程):
如果isForgot为false(登录或注册流程),isPasscodeEntry JSX将不会有条件地呈现,并且不会显示“重置密码”按钮。相反,它将显示“登录”或“注册”按钮,这取决于isLogin是true还是false。
下面是LoginScreen的jsx:

function AuthContent({ isLogin, isForgot, isPasscodeEntry, setIsPasscodeEntry, onSignUp, onLogin, onForgot }) {...
return (
        <SafeAreaView style={styles.container}>
            {!isForgot ? (
                <>
                    
                    {isPasscodeEntry ? (
                        <>
                            <AuthContent
                                isLogin={isLogin}
                                isPasscodeEntry={isPasscodeEntry}
                                setIsPasscodeEntry={() => setPasscodeEntry}
                                // onSignUp={signUpHandler}
                                // onLogin={loginHandler}
                            />
                            <View style={styles.forgot}>
                                <Button onPress={() => { setIsForgot(true), setIsLogin(false) }}>
                                    Forgot Password
                                </Button>
                            </View>
                            <View style={styles.buttons}>
                                <Button onPress={() => setIsLogin(!isLogin)}>
                                    {isLogin ? 'Register Here' : 'Login Here'}
                                </Button>
                                {isLoading && <LoadingOverlay />}
                            </View>
                        </>
                    ) : (
                        <>
                            <AuthContent
                                isLogin={isLogin}
                                isPasscodeEntry={isPasscodeEntry}
                                setIsPasscodeEntry={() => setPasscodeEntry}
                                onSignUp={signUpHandler}
                                onLogin={loginHandler}
                            />
                            <View style={styles.forgot}>
                                <Button onPress={() => { setIsForgot(true), setIsLogin(false) }}>
                                    Forgot Password
                                </Button>
                            </View>
                            <View style={styles.buttons}>
                                <Button onPress={() => setIsLogin(!isLogin)}>
                                    {isLogin ? 'Register Here' : 'Login Here'}
                                </Button>
                                {isLoading && <LoadingOverlay />}
                            </View>
                        </>
                    )}
                </>
            ) : (
                <>
                    <AuthContent
                        isLogin={false}
                        isForgot={isForgot}
                        onLogin={forgotHandler}
                        onForgot={forgotHandler}
                        isPasscodeEntry={isPasscodeEntry}
                        setIsPasscodeEntry={() => setPasscodeEntry()}
                    />
                    
                    <View style={styles.buttons}>
                            <Button onPress={() => setIsForgot(false)}>
                            Go Back
                        </Button>
                        {isLoading && <LoadingOverlay />}
                    </View>
                </>
            )}
        </SafeAreaView>
    );
}

export default LoginScreen;

下面是AuthForm的jsx:

function AuthForm({ isLogin, isForgot, isPasscodeEntry, setIsPasscodeEntry, onSubmit, credentialsInvalid }) {...

return (
        <KeyboardAvoidingView
            style={{ flex: 1 }}
            behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
            keyboardVerticalOffset={Platform.OS === 'ios' ? 0 : 100}
        >
            <View style={styles.form}>
                <View>
                    {isForgot ? (
                        <Input
                            label="Email Address"
                            onUpdateValue={updateInputValueHandler.bind(this, 'email')}
                            value={enteredEmail}
                            textInputConfig={{
                                onChangeText: (text) => updateInputValueHandler('email', text),
                                value: enteredEmail,
                            }}
                            keyboardType="email-address"
                            isInvalid={emailIsInvalid}
                        />
                    ) : (
                        <>
                            <Input
                                label="Email Address"
                                onUpdateValue={updateInputValueHandler.bind(this, 'email')}
                                value={enteredEmail}
                                textInputConfig={{
                                    onChangeText: (text) => updateInputValueHandler('email', text),
                                    value: enteredEmail,
                                }}
                                keyboardType="email-address"
                                isInvalid={emailIsInvalid}
                            />

                            {!isLogin && !isForgot && (
                                <Input
                                    label="Confirm Email Address"
                                    onUpdateValue={updateInputValueHandler.bind(this, 'confirmEmail')}
                                    value={enteredConfirmEmail}
                                    keyboardType="email-address"
                                    isInvalid={emailsDontMatch}
                                />
                            )}

                            <Input
                                label="Password"
                                onUpdateValue={updateInputValueHandler.bind(this, 'password')}
                                value={enteredPassword}
                                textInputConfig={{
                                    onChangeText: (text) => updateInputValueHandler('password', text),
                                    value: enteredPassword,
                                    secureTextEntry: true,
                                }}
                                isInvalid={passwordIsInvalid}
                            />

                            {!isLogin && !isForgot && (
                                <Input
                                    label="Confirm Password"
                                    onUpdateValue={updateInputValueHandler.bind(this, 'confirmPassword')}
                                    value={enteredConfirmPassword}
                                    textInputConfig={{
                                        onChangeText: (text) => updateInputValueHandler('confirmPassword', text),
                                        value: enteredConfirmPassword,
                                        secureTextEntry: true,
                                    }}
                                    isInvalid={passwordsDontMatch}
                                />
                            )}

                            {isPasscodeEntry && (
                                // Add your passcode entry component here
                                <>
                                    <Input
                                        label="Enter one-time passcode"
                                        onUpdateValue={updateInputValueHandler.bind(this, 'passcode')}
                                        value={enteredCode}
                                        textInputConfig={{
                                            onChangeText: (text) => updateInputValueHandler('passcode', text),
                                            value: enteredCode,
                                            secureTextEntry: true,
                                        }}
                                        isInvalid={passwordIsInvalid}
                                    />
                                </>
                            )}
                        </>
                    )}
                </View>
                <View style={styles.buttons}>
                    {isForgot ? (
                        // Call setIsPasscodeEntry(true) when isForgot is true
                        <Button onPress={() => { submitHandler(); setIsPasscodeEntry(); }}>
                            Reset Password
                        </Button>
                    ) : (
                        // Call submitHandler when isForgot is false
                        <Button onPress={submitHandler}>
                            {isLogin ? 'Log In' : 'Sign Up'}
                        </Button>
                    )}
                </View>
            </View>
        </KeyboardAvoidingView>
    );
}

export default AuthForm;
mxg2im7a

mxg2im7a1#

预期:“* 如果isForgot为true(密码重置流程),则在按下“重置密码”按钮时,将有条件地呈现isPasscodeEntry JSX。*”
主要问题:您的密码输入组件只有在isForgot设置为false,isPasscodeEntry设置为true时才会根据您的条件进行渲染。这不是你在问题中计划的逻辑。
**解决方案:**将passcode entry组件及其条件渲染移动到isForgot设置为true的分支中

我不能告诉你精确的解决方案,因为你有复杂的嵌套条件。
我建议:

  • 改进变量命名以提高可读性
  • 检查所有条件,确保所有条件渲染都按预期工作。
  • 用一个有意义的函数 Package 你的视图组件,这样你就可以很容易地知道你在每种情况下渲染的是什么。
  • 避免嵌套三元运算符或if else条件(创建混乱的分支逻辑),而应使用组合逻辑运算符

三进制逻辑示例:

isForgot ?
  isPasscodeEntry ?
    renderPasscodeEntry() :
    renderEmailInput()
: renderSomethingElse()

组合逻辑运算符备选:

<>
  {isForgot && hasPasscodeEntry && renderPasscodeEntry()}
  {isForgot && !hasPasscodeEntry && renderEmailInput()}
  {!isForgot && renderSomethingElse()}
</>

相关问题