Quantcast
Channel: Active questions tagged react-native+typescript - Stack Overflow
Viewing all articles
Browse latest Browse all 6287

React state is not returning the right value inside a function after update has been confirmed

$
0
0

I'm building a simple signup form in react native but it seems some states are not working properly. I know about the fact that states update asynchronously but still, I don't understand what is happening here

Signup component

import React, {useEffect, useState} from "react";import { StyleSheet, View, Pressable, ScrollView} from "react-native";import {AntDesign} from '@expo/vector-icons'import Text from '../components/Text'import Input from "../components/Input";import Button from "../components/Button";import Nope from "../utils/validator";import type { InputState } from "../components/Input";interface Props {}const initialInputState: InputState = {  errorMsg: '',  isValidated: false,  value: ''}const SignUp:React.FC<Props> = () => {  const [email, setEmail] = useState(initialInputState)  const [password, setPassword] = useState(initialInputState)  const [confirmPassword, setConfirmPassword] = useState(initialInputState)  const [isValidationTriggered, setIsValidationTriggered] = useState(false)  const [isValidated, setIsValidated] = useState(false)  function triggerValidation(){    setIsValidationTriggered(true)  }  const handleSubmit = () => {    console.log({isValidated, isValidationTriggered})    if(!isValidated){      console.log('Not validated')      !isValidationTriggered && triggerValidation()      return    }    const formData = {      email: email?.value,      password: password?.value,      confirmPassword: confirmPassword?.value    }    console.log({formData})  }  useEffect(() => {    setIsValidated(      (email?.isValidated &&      password?.isValidated &&      confirmPassword?.isValidated) ?? false    )  }, [email, password, confirmPassword])  useEffect(() => {    console.log(isValidated)  }, [isValidated])  return  (<ScrollView keyboardShouldPersistTaps="handled"><View style={styles.container}><View style={styles.header}><Text h1 bold>Sign up</Text></View><View style={styles.form}><Input           placeholder="Email or phone number"          validator={Nope.isEmail().isRequired().validate()}           triggerValidation = {isValidationTriggered}          onChangeState={state => setEmail(state)}          /><Input           secure           placeholder="Password"           validator={Nope.isMin(4).isRequired().validate()}          triggerValidation = {isValidationTriggered}          onChangeState={state => setPassword(state)}          /><Input           secure           placeholder="Confirm password"           validator={Nope.isEqual(password?.value ?? '', 'Passwords should match').validate()}          triggerValidation = {isValidationTriggered}          onChangeState={state => setConfirmPassword(state)}        /><Button           fullWidth           style={styles.topSpace}           disabled={isValidationTriggered? !isValidated : false}          onPress={() => handleSubmit()}><Text bold color="#fff">Sign up</Text></Button><Button secondary fullWidth style={styles.topSpace}><AntDesign name="google" size={24} color="#fff" style={{marginRight: 10}} /><Text bold color="#fff">Sign in with google</Text></Button></View><View style={styles.footer}><Text>Already have an account, </Text><Pressable><Text bold color="#1263f8">Sign in</Text></Pressable></View></View></ScrollView>  )}

Input component

import React, {useEffect, useRef, useState} from "react";import { StyleSheet, TextInput, View, ViewStyle} from "react-native";import type {StyleProp, KeyboardTypeOptions} from 'react-native'import Text from './Text'import IconButton from "./IconButton";import { Ionicons } from '@expo/vector-icons'interface Props {  placeholder?: string,  secure?: boolean  keyboardType?: KeyboardTypeOptions  style?: StyleProp<ViewStyle>  inputStyle?: {}  solid?:boolean  outlined?:boolean  bind?: [string, React.Dispatch<React.SetStateAction<string>>]  validator?: (text: string) => string  triggerValidation?:boolean  onChangeState?: (state: InputState) => void}export interface InputState {  value: string  errorMsg: string  isValidated: boolean}const Input:React.FC<Props> = ({  placeholder,   keyboardType,  secure,   style,   inputStyle,   solid,   outlined,   bind,   validator,   triggerValidation,  onChangeState}) => {  let inputRef = useRef<TextInput | null>(null)  const [value, setValue] = bind ? bind : useState('')  const [errorMsg, setErrorMsg] = useState('')  const [startValidation, setStartValidation] = useState(false)  const [showSecureText, setShowSecureText] = useState(false)  function changeTextHandler(text: string){    setValue(text)  }  function blurHandler(){    if(startValidation === false){      setStartValidation(true)    }  }  useEffect(() => {    if(startValidation && validator !== undefined){      setErrorMsg(validator(value))    }  }, [value, startValidation, validator])  useEffect(() => {    if(triggerValidation && !startValidation){      setStartValidation(true)    }  }, [triggerValidation, startValidation])  useEffect(() => {    if(onChangeState !== undefined){      onChangeState({        value,        errorMsg,        isValidated: /^\s*$/.test(errorMsg) && startValidation      })    }  }, [value, errorMsg, startValidation])  return  (<View style={[styles.inputWrapper, style]}><TextInput         placeholder={placeholder}        keyboardType={keyboardType}        secureTextEntry={secure && !showSecureText}        style={[          styles.input,           inputStyle,          (outlined || (!outlined && !solid))&& styles.outlined,          solid && styles.solid,          !/^\s*$/.test(errorMsg) && styles.error        ]}        value={value}        onChangeText={changeTextHandler}        onBlur={blurHandler}        ref={ref => inputRef.current = ref}      />      {        secure&& (<IconButton             style={styles.toggleBtn}             onPress={() => {              setShowSecureText(v => !v)              inputRef.current?.focus()            }}>            {              showSecureText              ? <Ionicons name="eye-off" size={24} color="#666" />              : <Ionicons name="eye" size={24} color="#666" />            }</IconButton>        )      }      {        !/^\s*$/.test(errorMsg)&& <Text color="#f00" sm style={styles.errorMsg}>{errorMsg}</Text>      }</View>  )}

When I submit the form after making sure the isValidated = true it still runs the !isValidated branch


Viewing all articles
Browse latest Browse all 6287

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>