No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Aprende todo un fin de semana sin pagar una suscripci贸n 馃敟

Aprende todo un fin de semana sin pagar una suscripci贸n 馃敟

Reg铆strate

Comienza en:

3D
10H
7M
50S

Estados independientes con useState

6/19
Recursos

Aportes 86

Preguntas 3

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Tambien podriamos agregar un setError(false), cuando se da click en el bot贸n comprobar鈥

<button
    onClick={() => {
      setLoading(true);
             setError(false);
        }} >
        Check
      </button>

Reto de la clase
manteniendo el mismo c贸digo, solo agregando un else con setError(false)

useEffect(
() => {
 if (loading) {
  setTimeout(() => {
   if (value !== SECURITY_CODE) {
    setError(true)
   }else{
    setError(false)
   }
   setLoading(false)
  }, 1000)
 }
}, [ loading ] )

Tambi茅n se le pudiera poner un setTimeout al setError para quitarlo. La otra forma que se me ocurre es que en el evento onChange al ejecutarse, poner setError(false), as铆 escribes en el input y nunca tendr谩s un error mostr谩ndose 馃槂

Yo simplemente agregaria un setError(false) al inicio del efecto

if (loading) {
      setError(false);
      setTimeout(() => {
        console.log("Haciendo la validaci贸n");

        if (value === SEGURITY_CODE) {
          setLoading(false);
        } else {
          setError(true);
          setLoading(false);
        }


        console.log("terminando la validaci贸n");
      }, 1000)
    }

Mi manera de solucionarlo es que cuado loading es true, llamamos a setError(false) para que desaparezca el mensaje y solo se vea el de 鈥淐argando鈥︹ desu茅s si el valor es igual al codgo de seguridad tambien ponemos setError(false) para que no nos estorbe.

React.useEffect(() => {
    console.log("Empezando...")

    if (!!loading) {
        setError(false);
        setTimeout(() => { 
            console.log("Haciendo la validacion...")
            if(value === SECURITY_CODE) {
                setLoading(false);
                setError(false);
            } else {
                setLoading(false);
                setError(true);
            }
            console.log("Terminando la validacion...")
        }, 2000)
    }

    console.log("Acabando...")
}, [loading])
// This function is called when the form is submitted
const onValidation = (e) => {
	e.preventDefault();
	setMessage('');
	setLoading(true);
};
{message && (
	<p className={error ? 'text-red-400' : 'text-green-400'}>{message}</p>
)}

Hice una funci贸n llamada handleChange() en donde el estado de error lo cambio a falso, de esta forma en cuanto el usuario modifique el texto del input, el mensaje de error desaparece 馃槂

const handleChange = (event) => {
    setValue(event.target.value);
    setError(false);
  }

<input
        type="text"
        placeholder="C贸digo de seguridad"
        value={value}
        onChange={(event) => handleChange(event)}
      />

Lo colocar铆a despu茅s de la validaci贸n de la variable loading:

useEffect(() => {

		if(!!loading){
			setError(false)
			setTimeout(()=> {
				console.log("Haciendo la validaci贸n")

				if(value!==SECURITY_CODE){
					setError(true)
				}
				setLoading(false)
				
				console.log("Terminando la validaci贸n")
			}, 3000)
		}
	}, [loading])

este es mi soluci贸n al problema que cuando le den click al boton el setError pase a false

Agregando el setError antes del setTimeout

React.useEffect(()=>{
        console.log("Empezando el efecto")
        if(!!loading){
            setError(false);
            setTimeout(()=>{
                setLoading(false);
                console.log("Haciendo la validacion")
                if (value!== SECURITY_CODE) {
                    setError(true);
                }
                
                console.log("Terminando la validacion")
            },3000)
        }
        console.log("Terminando el efecto")
    },[loading])

Realizar铆amos los siguientes cambios:

 <button
                onClick={handleValidar} >
                Comprobar
 </button>

Luego crear铆amos la siguiente funci贸n.

const handleValidar = () => {
        setError(false)
        setLoading(true)
    }

Y finalmente quedar铆a el useEffect asi:

 useEffect(() => {
        if (loading) {
            setTimeout(() => {
                if (value === SECURITY_CODE) {
                    setError(false)
                } else {
                    setError(true)
                }
                setLoading(false)
            }, 3000)
        }
    }, [loading])

Yo puse el setErro(false) en el input:

            <input 
                placeholder="Security Code"
                value={value}
                onChange={event=>{
                    setValue(event.target.value)    
                    setError(false  )                    
                }}

Yo quise usar un ternario en el c贸digo en vez de los if, else/

React.useEffect(()=>{
        const wrongCode = () =>{
            setLoading(false);
            setError(true);
        }
        if(!!loading){
            setTimeout(()=>{
                value === SECURITY_CODE ? setLoading(false) : wrongCode();
                
            }, 3000)
        }

    }, [loading])

Mi soluci贸n fue crear una funci贸n llamada validateError

const validateError = (event) => {
	setValue(event.target.value);
	setError(false);
};

Finalmente esta funci贸n la uso en el onClick

<input type="text" placeholder="C贸digo de seguridad" value={value} onChange={validateError}/>

Seg煤n yo la forma un poco mas eficiente y con mejor experiencia de usuario es quitar el error al momento que el usuario cambia el input nuevamente de la siguiente manera

comprobando primero si el error es true, de esta forma evitamos cambiar el estado a false cada que el usuario presione una tecla

<input placeholder="Codigo de seguridad" value={value}
            onChange={ev => {
               if (error) {
                  setError(false)
               }
               setValue(ev.target.value)
            }}/>

Se podria utilizar setError(false) , si el error es true, en onChange del input

La forma m谩s 贸ptima que pude encontrar:

React.useEffect(() => {
        if (loading) {
            setError(false);

            setTimeout(() => {
                setLoading(false);

                if (value !== SECURITY_CODE) {
                    setError(true);
                    return;
                }

                setError(false);
            }, 3000);
        }
    }, [loading]);

Para que desaparezca el t铆tula antes de empezar a cargar lo llamo antes de que entre al setTimeout !!!

React.useEffect(() => {
    console.log("Empezando el efecto");

    if (loading) {
      setError(false);
      setTimeout(() => {
        console.log("Haciendo la validaci贸n!!");
        if (value !== SECURITY_CODE) {
          setError(true);
        }
        setLoading(false);
        console.log("Terminando la validaci贸n!!");
      }, 3000);
    }
Creo que bastar铆a con colocar serError(false) en el onChange del input.. As铆 el render "limpiar铆a" el error cuando el usuario decida intentar otra entrada. Pero veo la diferencia con usar las clases, en cuyo caso el render ser铆a cuando cambie cualquier valor del estado ya que 茅ste es un 煤nico objeto global.

Mi aporte ser铆a este ->

  React.useEffect(() => {
    if (!!loading) {
      setError(false);
      setTimeout(() => {
        setError(value !== SECURITY_CODE);
        setLoading(false);
      }, 3000);
    }
  }, [loading]);

He estado viendo reels de midudev en IG y mencionaba que los if() a veces suman mucho c贸digo as铆 que es mejor retornar la validaci贸n, de esta forma te ahorras mucho c贸digo, as铆 mi soluci贸n m谩s r谩pida y sencilla es solo agregando una linea de c贸digo:

useEffect(()=>{
        if(loading){
            setTimeout(()=>{
                setError(value !== SECURITY_CODE)
                setLoading(false);
            }, 3000); 
        }
    }, [loading])

Con esta soluci贸n te evitas llamar m煤ltiples veces a setError() y solo lo llamas una vez pasandole la comparaci贸n, su resultado se traduce en true o false

if(value !== SECURITY_CODE){
          setError(true);
        }else{
          setError(false);
        }
        setLoading(false);
    React.useEffect(()=>{
        if (loading) {
            setTimeout(() => {
                setLoading(false)
                value !== SECURITY_CODE ? setError(true) : setError(false)
            }
            ,3000)
        }
    }, [loading])

Yo solo agregue el setError(false) en el eventListener OnChange.

onChange={(event) => {
                setValue(event.target.value);
                setError(false);
            }}

Asi lo hice yo 馃槂

 React.useEffect(()=>{
        

        if (!!loading){
            setError(false)
            setTimeout(()=>{

                if (value === SECURITY_CODE) {
                    setLoading(false)
                    setError(false)
                } else {
                    setLoading(false)
                    setError(true)
                }

            },500)
        }
    },[loading])

Mi soluci贸n fue envolver todo el c贸digo en una funci贸n de autenticaci贸n, donde por defecto setError cambie a false con cada clic al bot贸n y setLoading a true

Recomiendo la extensi贸n de React para ver los valores de props, y states: En firefox: https://addons.mozilla.org/en-US/firefox/addon/react-devtools/

value === SECURITY_CODE
? setError(false)
: setError(true);

        value === SECURITY_CODE 
        ?  setLoading(false)
        :  setLoading(false);

mi solucion

if(!!loading){
            setError(false);
            setTimeout(() => {
                console.log('haciendo la validacion')
                if (value === SECURITY_CODE) {
                    setLoading(false)
                    setError(false)
                }else{
                    setLoading(false)
                    setError(true);
                }
                console.log('terminando la validacion');
            }, 3000);
        }

Se puede resolver cambiando el estado del loading en caso de que sea correcta la contrase帽a o no:

if (value !== SECURITY_CODE) {
                    setError(true);
                } else {
                    setError(false);
                }
                setLoading(false);

Le di soluci贸n al reto agregando un condicional antes de ingresar al setTimeout que valide si el estado de error se encuentra activado

    React.useEffect(() => {
        console.log('Effect start');

        if (loading) {
            console.log('Doing validation');

            if (error) {
                setError(false)
            }

            setTimeout(()=>{
                if (value != SECURITY_CODE){
                    setError(true);
                }

                setLoading(false);
            }, 3000)
        } else {
            console.log('Loading state hasn\'t already changed')
        }

        console.log('finishing validation');

    }, [loading]);

Lo hice de esta manera tambi茅n para evitar que el estado de error se actualizara de forma iterativa cada vez que el efecto se viera implementado y asegurar que solamente mute el estado cuando sea necesario.

Esta fue mi solucion para el reto del error:

        <input 
        type='text' 
        placeholder='c贸digo de seguridad'
        value={value}
        onChange={(event)=>{
            setValue(event.target.value)
            setError(false) 
        }}
        />

Lo puse en el input ya que me parece lo m谩s l贸gico.

Aqu铆 mi soluci贸n. Al momento de presionar el bot贸n se activa el estado de loading y se desactiva el estado de error. De esta manera si anteriormente hubo un error este desaparecer谩, luego, en la validaci贸n este validar谩 si el c贸digo es el correcto, en caso de que no sea as铆, activar谩 el estado de error, finalmente, aunque haya coincidido o no el c贸digo, el estado de loading se desactivar谩.
Aqui primero el c贸digo del bot贸n.
Aqu铆 el c贸digo del efecto.

Realic茅 la validaci贸n para ambos casos, pero con un setTimeout donde indica que est谩 cargando los resultados posteriores, eval煤a si es correcto, muestra el mensaje y se vuelve al estado inicial del input. Lo mismo para la condici贸n de error. C贸digo:

import React, { Fragment, useEffect, useState } from 'react';

const PASSWORD = 'react';

function UseState(props){
  const [error, setError] = useState(false);
  const [loading, setLoading] = useState(false);
  const [login, setLogin] = useState('');
  const [password, setPassword] = useState(false)

  //cargar validacion
  const handleClick = () => {
    setLoading(true)
  }

  //login correcto
  const loginCorrect = () => {
    setTimeout(() => { setLoading(false) }, 2000);
    setTimeout(() => setPassword(false), 4000);
    setTimeout(() => setPassword(true), 2000);
  }

  //login incorrecto
  const loginIncorrect = () => {
    setTimeout( () => { setLoading(false); setError(true) }, 2000);
    setTimeout( () => { setError(false) }, 4000)
  }

  useEffect(() => {    

      loading ?
      setTimeout(() => { 
        login === PASSWORD ?
        loginCorrect()
                           : 
        loginIncorrect()})
              :
      console.log('Validacion Finalizado.')
  }, [handleClick]);
  
  return (
    <Fragment>
      <h2>Eliminar {props.name}</h2>
      <p>Por favor, escribe el codigo de seguridad.</p>
      <input
        type="text" 
        placeholder='Codigo de seguridad' 
        value={login}
        onChange={(e) => {
          setLogin(e.target.value);
        }}
        />
      <button
        onClick={() => handleClick()}
        className='btn btn-secondary'
      >
        Comprobar</button>
      {loading && <p className='bg-success'>Validando ...</p>}

      {error && <p className='bg-danger text-white'>Error: el codigo no es valido.</p>}

      { password && <h2>Login correcto 鉁</h2>}
    </Fragment>
  );
}

export { UseState };

Yo lo resolvie asi:

./UseState.js
En la 鈥渃onsulta a la API鈥

                setTimeout(
                    ()=>{
                        console.log("Haciendo la validacion")
                        setError(value !== SECURITY_CODE);
                        setLoading(false)
                        console.log("Terminando la validacion")
                    },
                    3000
                )     

Y en maquetado del componente, especificamente en el mensaje de error:

            {(error && !loading) && (
                <p>Error: El codigo es incorrecto</p>
            )}

Espero les guste mi solucion!

no creo que sea la mas optima, pero si funciona

if( value === SECURITY_CODE ) {
                    setError(false);
                    setLoading(false);
                } else {
                    setError(true);
                    setLoading(false);
                }

Lo resolvi con un setTimeout as铆:

React.useEffect(() => {
        console.log("Empezando el Efecto")

        if (!!loading) {
            setTimeout(() => {
                console.log("Haciendo la validaci贸n")

                if (value === SECURITY_CODE) {
                    console.log(value)                    
                    setLoading(false)                    
                } else {
                    console.log(value)
                    setLoading(false)
                    setError(true)
                    setTimeout(() => {
                        setError(false)
                    }, 1000)                   
                }
                
                
                console.log("Terminando la validaci贸n")
            }, 2000);
            console.log("Terminando el Efecto")            
        }
    }, 
    [loading]);

Mi soluci贸n fue:

  1. Cree un nuevo estado para cuando el c贸digo sea v谩lido, iniciado en 鈥渇alse鈥 para mostrar un mensaje cuando sea correcto el c贸digo.

  2. cada vez que el usuario presiona el bot贸n para validar este, restaura los estados de error y de v谩lido para limpiar de mensajes el componente.

  3. Dependiendo si el c贸digo es correcto o incorrecto, modifico el estado de error o de v谩lido para mostrar el msm correspondiente.

  4. Adicionalmente agregu茅 el m茅todo toLowerCase() para validar el c贸digo siempre en min煤sculas, independientemente del valor ingresado por el usuario.

Solucion menos indicada pero la mas facil

    React.useEffect(()=>{
       
        if(!!loading){

            setTimeout(()=>{
                console.log('Validando')
                if(value === CODE_SECURITY){
                    setLoading(false)
                    setError(false)

                }else{
                    setLoading(false)
                    setError(true)
                }

                console.log('Final validacion')

            },3000);
        }



    },[loading]);

Mi soluci贸n al reto de la clase fue cambiar el estado del error cuando se realiza un cambio en el value del input, ya que a煤n no se ha realizado la nueva validaci贸n, por lo tanto no se conoce si la respuesta tendr谩 un error:
<input placeholder="C贸digo de seguridad"
value={ value}
onChange={(event) => {
setError(false);
setValue(event.target.value)}}/>

Mi soluci贸n. Pero tiene el problema de que siempre muestra un mensaje Aunque se aya recargado la pagina.

{
	loading
	?<p>Cargando...</p>
	:!error
	?<p>Aceptado: El codigo es correcto</p>
	:<p>Error: El codigo es incorrecto</p
 }

MI soluci贸n

	useEffect(() => {
		console.log('Ready effect');

		if(loading){
			setTimeout(() => {
				console.log("Haciendo validaci贸n");
				if (word !== SECURITY_CODE) {
                    setError(true);
                }
				setLoading(false)
				console.log("Terminando validaci贸n");
			},2000)
		}
		
		console.log('Finish effect');
	},[loading]) /* El componentWillMount seria la priemra carga */

	const handleState = () => {
		setError(false)
		setLoading(true)
	}

	const handleChange = (e) => {
		setError(false)
		se
        if(!!loading){
            setTimeout(()=>{
                console.log("Haciendo la validaci贸n")

                if(value === SECURITY_CODE) {//comentario
                    setLoading(false);
                    console.log('acceso permitido')
                }else{
                    setError(true)
                    setLoading(false)
                    setTimeout(()=>{
                        setError(false)
                    },5000)
                }

Les comparto mi soluci贸n

Tambi茅n se podr铆a poner en solo dos l铆neas.

la solucion al reto qu ese me ocurre es colocando un setError(false) antes del setTimeout como podemos ver:

  React.useEffect(() => {
    console.log("empezando el efecto");
    if (!!loading) {
      setError(false);
      setTimeout(() => {
        console.log("haciendo la validacion");
        if (value !== SECURITY_CODE) {
          setError(true);
        }
        setLoading(false);

        console.log("terminando la validacion");
      }, 3000);
    }

    console.log("terminando el efecto");
  }, [loading]);

La otra que se me ocurre es cuando damos click en el boton dar un setError(false).

 <button
        onClick={() => {
          setLoading(true);
          setError(false);
        }}
      >

y por ultimo seria ponerlo en el onChange del input aunque creo que haria que la aplicacion sea poco eficiente lo dejo al juicio de los demas:

  <input
        placeholder="Codigo de seguridad"
        value={value}
        onChange={(event) => {
          setValue(event.target.value);
          setError(false);
        }}
      />

Mi solucion es agregar una condici贸n adicional donde se esta mostrando el parrafo, la condici贸n quedaria si error es true pero loading es false muestra el error de esta manera no se muestran los dos parrafos al mismo tiempo. Y adiciono un else para cambiar el estado del error en caso de que coincida la palabra

  useEffect(() => {
        if (!!loading) {
            setTimeout(() => {
                if (value !== SECURITY_CODE) {
                    setError(true);
                } else {
                    setError(false);
                }
                setLoading(false);
            }, 3000);
        }
    }, [loading]);

    return (
        <div>
            <h2>Eliminar {name}</h2>
            <p>Por favor, escribe el c贸digo de seguridad.</p>
            {error && <p>Error: El c贸digo es incorrecto</p>}
            {loading && <p>Cargando...</p>}
            <input value={value} onChange={(e) => setValue(e.target.value)} placeholder="C贸digo de seguridad" />
            <button onClick={() => setLoading(true)}>Comprobar</button>
        </div>
    );

function UseState({ name }) {
    const [value, setValue] = useState('')
    const [error, setError] = useState(false)
    const [loading, setLoading] = useState(false)
    //executes the code when it fulfills the conditions given in the second argument
    useEffect(() => {
        //validation to avoid execution on page loading
        loading &&
            setTimeout(() => {
                setLoading(false)
                value !== SECURITY_CODE ? setError(true) : setError(false)
            }, 1000)
    }, [loading, value])

    return (
        <div>
            <h2>Delete {name}</h2>
            {!!loading ? (
                <p>Loading...</p>
            ) : !error ? (
                <p>Please, insert your security code</p>
            ) : (
                <p>Error: incorrect code</p>
            )}

            <input
                placeholder="security code"
                value={value}
                onChange={({ target }) => setValue(target.value)}
            />
            <button onClick={() => setLoading(!loading)}>Check it</button>
        </div>
    )
}

useEffect(()=>{
        if(loading  )
        {

            console.log("change state loading")
            setTimeout(()=>{
               
                if(value !== SECURITY_CODE)
                {
                    setError(true);
                    
                }
                if(value === SECURITY_CODE)
                {
                    if(error)
                    {
                        setError(false);
                    }
                    
                }
                SetLoading(false);
          
               
            },2000) 
        }
       
    },[loading])

Utilic茅 otro useEffect, para que inmediatamente el usuario cambie el valor del input se elimine el mensaje de error:

 useEffect(() => {
      setError(false)
    }, [value])

Mi soluci贸n al reto:

        if (!!loading) {
            setError(false);
            setTimeout(() => {
                if (value !== SECURITY_CODE) {
                    setError(true);
                }
                setLoading(false);
            }, 3000);
        }
            	

Le agregu茅 el estado del error a useEffect y luego retorn茅 un array seteando los valores, es la manera que se me ocurri贸

<button onClick={() => [setLoading(true), setError(false)]}>Comprobar</button>

A mi me parece que lo mejor es poner el setError en el boton de comprobar

React.useEffect(() => {
    if (loading) {
      setTimeout(() => {
        if (value !== SECURITY_CODE) {
          setError(prev => !prev);
        } else if ((value === SECURITY_CODE) && error) {
          setError(prev => !prev);
          setLoading(false);
        }
        setLoading(false);
      }, 1000)
    }
  }, [loading, error]);

Yo simplemente agregue un setError(false) cuando el value del elemento sea verdadero y ya.

Mi solucion

  React.useEffect(() => {
    if (!!loading) {
      setError(false);
      setTimeout(() => {
        if(value === SECURITY_CODE) {
          setLoading(false);
        } else {
          setLoading(false);
          setError(true);
        }
        
      }, 3000);
    }
  }, [loading]);

Antes de la validaci贸n:

error ? setError(false) : null;
if(value !== SECURITY_CODE)

Buenas, mi solucion fue agregar dos cosas, junto a la primera validacion de setLoading false, tambien coloque setError false, y en el return, se coloco una segunda validacion para que solo mostrara el parrafo de error si error era true y si loading era false:

        if(loading){
            setTimeout(()=>{
                console.log('validating')
                if(value=== SECURITY_CODE){
                    setLoading(false);
                    setError(false);
                }else{
                    setError(true);
                    setLoading(false);
                }
                console.log('ok')
            },3000)
        }

        console.log('finishing')
    },[loading])


    return(
        <div>
            <h2>Delete {name}</h2>
            <p>Write the access code</p>
            {(error && !loading) && <p>
                Error, incorrect code
            </p>}

Mi soluci贸n fue crear una funci贸n onChangeInput y quitar el alert de error dentro de esta:

const onChangeInput = (e) => {
   setValue(e.target.value)
   setError(false)
}
<input
   type='text'
   placeholder="C贸digo de seguridad"
   className="border border-gray-200 rounded-md px-1 py-1 mr-2 outline-none
   focus:ring-2 focus:ring-blue-400"
   value={value}
   onChange={(e) => onChangeInput(e)}
/>

Me salio as铆:

if (!!loading) {

setTimeout(() => {

    console.log("Haciendo la validaci贸n");
    if (value !== SECURITY_CODE) {
                    setLoading(true);
                    setError(true);
        } else {
                     setError(false)
          }
            setLoading(false)
          console.log("T茅rminando la validaci贸n");

            }, 3000);
        } 

Yo solamente agregar铆a el setError(false) en el evento onClick del bot贸n.

  React.useEffect(() => {
    console.log("Empezando el efecto");
    if (!!loading) {
      setTimeout(() => {
        console.log("Haciendo la validacion");
        if (value !== SECURITY_CODE) {
          setError(true);
        } else {
          setError(false);
        }
        setLoading(false);
        console.log("Terminando la validacion");
      }, 3000)
    }
    console.log("Finalizando el efecto");
  }, [loading]);
  return (
    <div>
      <h2>Eliminar {name}</h2>
      <p> Por favor, escribe el c贸digo de seguridad</p>

      {error && !loading && (
        <p>El c贸digo es incorrecto</p>
      )}
      {loading && (
        <p>Cargando ...</p>
      )}

      <input placeholder="C贸digo de seguridad"
        value={value}
        onChange={(event) => { setValue(event.target.value) }}
      />
      <button onClick={() => setLoading(!loading)}> Comprobar</button>
    </div >
  )

La forma que yo creo que es m谩s 贸ptima es usando un solo estado que maneje el status de la llamada a la API:

const [status, setStatus] = useState('idle') // idle, pending, resolved, rejected

Art铆culo de Kent C. Dodds que habla sobre esto:
https://kentcdodds.com/blog/stop-using-isloading-booleans

C贸digo completo:

export default function UseState() {
  const [status, setStatus] = useState('idle') // idle, pending, resolved, rejected
  const [value, setValue] = useState('');

  useEffect(() => {
    if (status === 'pending') {
      setTimeout(() => {
        if (value === SECURITY_CODE) {
          setStatus('resolved');
        } else {
          setStatus('rejected');
        }
      }, 2000)
    };
  }, [status, value]);

  return (
    <div>
      <h2>Eliminar UseState</h2>
      <p>Por favor, bla bla bla</p>

      {status === 'rejected' && (
        <p style={{ color: 'salmon' }}>Error: c贸digo incorrecto</p>
      )}

      {status === 'pending' && (
        <p style={{ color: 'lightblue' }}>Cargando...</p>
      )}

      <input 
        type="text"
        placeholder='c贸digo de seguridad'
        value={value}
        onChange={(e) => setValue(e.target.value)}
      />
      <button
        onClick={() => setStatus('pending')}
      >
        Comprobar
      </button>
    </div>
  );
}

Colocando la validaci贸n dentro del if al hacer click en el boton con el codigo incorrecto y luego al correcto, permanece los 3 segudos de espera el mensaje de error y luego se elimina.

if (!!loading) {
            setTimeout(() => {
                console.log("Ejecutando validacion")

                if(value === SECURITY_CODE) {
                    setLoading(false);
		    setError(false);
                } else {
                    setError(true);
                    setLoading(false);
                }

                console.log("Terminando validacion")
            }, 3000)
        }

Pero lo ideal es que al momento de hacer click nuevamente se elimine el error y quede en loading, lo que hice fue colocar dentro del button que el error sea (false), asi cada vez que lo utilizamos se elimina el mensaje.

<button
                onClick={() => {
                    setError(false);
                    setLoading(!loading);
}}
            >Comprobar</button>
if (loading) {
      setTimeout(() => {
        if (value !== SECURITY_CODE) {
          setLoading(false);
          setError(true);
          return; 
        }
        setLoading(false);
        setError(false);
      }, 2000);

La forma mas simple que se me ocurrio fue poner el setError(false), antes del timeout, para asegurarnos que sin importar si esta correcta o incorrecta la contrasenia, se desmonte el componente de error cada vez que se vaya a volver a comprobar.

   React.useEffect(()=> {
        console.log('Empezando el efecto');
        if(loader){
            setError(false);
            setTimeout(()=>{
                console.log('Haciendo la validacion');
                if(value === SECURITY_CODE){
                } else{
                    setError(true);
                }

                setLoader(false);
    
                console.log('Terminando la validacion');
            }, 2000);
        }
        console.log('Terminando el efecto');
    }, [loader])

Yo lo puse al principio de cada comprobaci贸n para que inicie sin errores y separado
de toda la l贸gica de loading para que esta parte del c贸digo pueda cambiar inclusive desaparecer
sin problemas pero el error siempre que resuelto.

<button onClick={() => {
	setError(false)
	setLoading(true)
}}>
  Comprobar
</button>
if (value !== SECURITY_CODE) {
	setError(true);
} else if (!!error) {
	setError(false);
}
setLoading(false);

As铆 es como yo lo solucione

const SECURITY_CODE = "paradigma";

function handleInput(e, setValue) {
  setValue(e.target.value);
}

function handleClick(setLoading, value, setValidation) {
  if (value === SECURITY_CODE) {
    setValidation("Continue");
  } else {
    setValidation("Error");
  }
  setLoading(true);
}

function UseState({ name }) {
  const [value, setValue] = React.useState("");
  const [validation, setValidation] = React.useState("");
  const [loading, setLoading] = React.useState(false);

  React.useEffect(() => {
    if (loading) {
      setTimeout(() => {
        setLoading(false);
      }, 1000);
    }
  }, [loading]);

  return (
    <div>
      <h2>Eliminate {name}</h2>
      <p>Please, type security code</p>

      {validation && !loading && <p>{validation}</p>}
      {loading && <p>Loading...</p>}

      <input
        onChange={(e) => handleInput(e, setValue)}
        type="text"
        placeholder="Secutiry code"
      />
      <button onClick={() => handleClick(setLoading, value, setValidation)}>
        Check
      </button>
    </div>
  );
}

Retro de la clase

Lo primero que se me ocurrio era meterle la condicion directamente al setError para actualizar el estado.

    useEffect(() => {
        console.log("Empezando el efecto");

        if (loading) {
            setTimeout(() => {
                console.log("Haciendo la validacion");

                setError(value !== SECURITY_CODE);
                setLoading(false);
                
                console.log("Terminando la validacion");
            }, 2000);
        }

        console.log("Terminando el efecto");
    }, [loading]);
React.useEffect(() => {
        console.log('Principio efecto');
        if(!!loading){
            setError(false);
            setTimeout(() => {
                console.log('Haciendo validacion');
                if(value !== SECURITY_CODE){
                    setError(true);
                }
                setLoading(false);
                console.log('Final validacion');
            }, 2000)
        }
        console.log('final efecto');
    },[loading])

De esta forma solo se aplicara el cambio de estado solo cuando se le de al boton que cambia el estado de carga.

Esta fue la primera forma que use. Aunque como vi en los comentarios una opci贸n que usar menos recursos es en el onClick o el inicio de useEffect

    onChange={(event) => {
          setError(false);
          setValue(event.target.value);
        }}

Simplemente valide si el error era true y quitarlo antes de validar.

    useEffect(() => {
        console.log('Empezando el estado')
        if(!!loading) {
            if(error) setError(false)
            setTimeout(() => {
                console.log('Haciendo la validaci贸n')
                
                setLoading(false)
                if(value !== SECURITY_CODE) {
                    setError(true)
                }
                
                console.log('Terminando la validaci贸n')
            }, 3000)
        }

        console.log('Terminando el efecto')
    }, [loading])
import { useState, useEffect } from "react";

const SECURITY_CODE = "parapeto";

export const UseState = (props) => {
  const [value, setvalue] = useState("");
  const [error, seterror] = useState(false);
  const [loading, setloading] = useState(false);

  useEffect(() => {
    if (loading)
      setTimeout(() => {
        if (value !== SECURITY_CODE) seterror(true)
        setloading(false);
      }, 1000);
  }, [loading]);

  const handleInput = (e) => {
    setvalue(e.target.value);
  };

  const handleClick = () => {
    seterror(false)
    setloading(true);
  };

  return (
    <>
      <h2> Eliminar {props.name} </h2>
      <p> Por favor escribe el c贸digo de seguridad </p>

      {error && <p> 鉂 Error: c贸digo incorrecto </p>}
      {loading && <p> 鈴 Cargando </p>}

      <input
        placeholder="c贸digo de seguridad"
        onChange={handleInput}
        value={value}
      />
      <button onClick={handleClick}> Comprobar </button>
    </>
  );
};

Con algunas modificaciones UseState.js estar铆a de la siguiente manera:

import React from 'react'

const SECURITY_CODE = 'paradigma';

function UseState({ name }) {
    const [value, setValue] = React.useState('');
    const [error, setError] = React.useState(false);
    const [loading, setLoading] = React.useState(false);

    const onClick = (event) => {
        setLoading(true)
    }

    const onChange = (event) => {
        setValue(event.target.value)
    }

    const commentEnterSubmit = (event) => {
        if (event.key === "Enter" && event.shiftKey === false) {
            return onClick(event);
        }
    }

    React.useEffect(() => {
        console.log("Starting the effect");

        if (!!loading) {
            setTimeout(() => {
                console.log("Doing the validation");

                if(value === SECURITY_CODE){
                    setLoading(false);
                    setError(false);
                }
                else{
                    setLoading(false);
                    setError(true);
                }

                console.log("Finishing the validation");
            }, 2000);
        }

        console.log("Finishing the effect");
    }, [loading]);

    return (
        <div>
            <h2>Delete {name}</h2>

            <p>Please enter the security code</p>

            {error && (
                <p>Error: Security code is incorrect</p>
            )}
            {loading && (
                <p>Loading...</p>
            )}

            <input 
                placeholder="Security Code"
                value={value}
                onChange={onChange}
                onKeyPress={commentEnterSubmit}
            />

            <button
                onClick={onClick}
            >Check</button>
        </div>
    );
}

export { UseState }

No se que tan buena sea mi soluci贸n pero ahi esta XD, a la siguiente clase!

React.useEffect(() => {
    if (loading) {
      console.log("Empezando el efecto");
      setTimeout(() => {
        console.log("Empezando la validaci贸n");
        if (value !== SECURITY_CODE) {
            setError(true);
        }
        setLoading(false)
        console.log("Terminando la validaci贸n");
      }, 3000);
      setTimeout(() => {
          setError(false);
      }, 5000)
      console.log("Terminando el efecto");
    }
  }, [loading]);

Reto de la clase
Yo lo soluione cambiando cambiando el estado de Error a false cada vez que modifiquemos nuestro input

<input
          placeholder="codigo de seguridad"
          value={value}
          onChange={event=>{ 
          	setError(false);
                setValue(event.target.value);
          }
        }
 />
<  React.useEffect( () => {
    console.log("empezando el efecto")

    if(!!loading){
      setTimeout( () => {
        console.log("haciendo la validacion")

        if(value === SECURITY_CODE){

          setError(false);

        }else {
          setError(true);
        }

        setLoading(false)



        console.log("Terminando la validaciin la validacion")
        
      }, 3000 )
    }
import React from "react";

const SECURITY_CODE = "paradigma";

function UseState({ name }) {
  const [value, setValue] = React.useState('');
  const [error, setError] = React.useState(false);
  const [loading, setLoading] = React.useState(false);

  console.log(value);

  React.useEffect(() => {
    console.log("Starting the effect");

    if(!!loading) {
      setTimeout(() => {
        console.log("Doing the validation");

        if(value === SECURITY_CODE) {
          setLoading(false);
          setError(false);
      } else {
        setError(true);
          setLoading(false);
      }
        console.log("Finishing the validation");
      }, 1000);
    }

    console.log("Finishing the effect");
  }, [loading]);

  return (
    <div>
      <h2>Delete {name}</h2>

      <p>Please enter the security code</p>

      {(error && !loading) && (
        <p>Error: Security code is incorrect</p>
      )}

      {loading && (
        <p>Loading...</p>
      )}

      <input
        placeholder="Security Code"
        value={value}
        onChange={(event) => {
          //setError(false);
          setValue(event.target.value);
        }}
      />

      <button
        onClick={() => {
          setLoading(true);
          //setError(false);
          }}
      >Check</button>
    </div>
  );
}

export { UseState };

Soluci贸n del reto:
Para conseguir que el mensaje de error desaparezca mientras carga y vuelva aparecer si hay error, entonces escribi este simple codigo:

React.useEffect(()=>{
        console.log('Empezando el efecto');

        if(loading){
            setError(false);
            setTimeout(()=>{
                console.log("Haciendo la validaci贸n xd");
                if(value === SECURITY_CODE){
                    setLoading(false);

                }else{
                    setError(true);
                    setLoading(false);
                }
                console.log("Terminando la validaci贸n");
            },1500)
        }

        console.log('Terminando el efecto');
    },[loading]);

Un hechizo simple, pero efectivo.

Tengo dos soluciones, la primera es la siguiente.

 useEffect(()=>{
        console.log('Empezando el efecto')
        if ( !!loading ) {
            setTimeout(()=>{
                console.log('Haciendo la validaci贸n');

                if ( value !== SECURITY_CODE ) {
                    setError(true);
                } else {
                    setError(false);
                }
                setLoading(false);

                console.log('Terminando la validaci贸n');
            },3000);
        }
        console.log('Terminando el efecto')
    }, [loading]);

Pero hay un problema, gr谩ficamente se seguira viendo el Error mientras se realiza el useEffect, por lo cual hice esta segunda opci贸n.

useEffect(()=>{
        console.log('Empezando el efecto')
        if ( !!loading ) {
            setError(false);
            setTimeout(()=>{
                console.log('Haciendo la validaci贸n');

                if ( value !== SECURITY_CODE ) {
                    setError(true);
                }
                setLoading(false);

                console.log('Terminando la validaci贸n');
            },3000);
        }
        console.log('Terminando el efecto')
    }, [loading]);

Hola, a mi se me ocurr铆a hacer lo siguiente.
Al principio de la validaci贸n de effect hacer set de error a false:

  useEffect(() => {    
    if(loading){
      setError(false)
      setTimeout(() => {
        console.log("haciendo la validaci贸n")

        if(value !== SECURITY_CODE){
          setError(true);
        }
          setLoading(false);

        console.log("terminando la validaci贸n")
      }, 1500);
    }
  },[loading])

o haciendole una validaci贸n al mismo error

  useEffect(() => {    
    if(loading){
      
      if(error){
        setError(false)
      }
      setTimeout(() => {
        console.log("haciendo la validaci贸n")

        if(value !== SECURITY_CODE){
          setError(true);
        }
          setLoading(false);

        console.log("terminando la validaci贸n")
      }, 1500);
    }
  },[loading])

lo hice asi

Esta fue la manera que yo lo solucione usando TS

import { ChangeEvent } from "react";
import { useEffect, useState } from "react";
import { UseStateProps } from "../interfaces/interfaces";

const SECURITY_CODE = "paradigma";
export const UseState = ({ name }: UseStateProps) => {
  const [error, setError] = useState<boolean>(false);
  const [loading, setLoading] = useState<boolean>(false);
  const [valueInput, setValueInput] = useState<string>("");
  const handleChange = (value: string) => {
    if (error) setError(false);
    setValueInput(value);
  };
  useEffect(() => {
    if (loading) {
      setTimeout(() => {
        setLoading(false);
        valueInput.trim().toLocaleLowerCase() !== SECURITY_CODE &&
          setError(true);
      }, 3000);
    }
  }, [loading]);
  return (
    <div>
      <h2> Eliminar {name}</h2>
      <p>Por favor, escribe el codigo de seguridad.</p>
      {error && (
        <p>
          <strong>Error:</strong> El codigo es incorrecto
        </p>
      )}
      {loading && (
        <p>
          <strong>Cargando....</strong>
        </p>
      )}
      <input
        placeholder="Codigo de seguridad"
        value={valueInput}
        onChange={(e: ChangeEvent<HTMLInputElement>) =>
          handleChange(e.target.value)
        }
      />
      <button onClick={() => setLoading(!loading)}>Comprobar</button>
    </div>
  );
};

Con un operador ternario:

useEffect(() => {
    if (loading) {
      setTimeout(() => {
        value === SECURITY_CODE ? setError(false) : setError(true)
        setLoading(false)
      }, 2000)
    }
  }, [loading, value])

Un setError(false) al inico del condicional

Una opci贸n podr铆a ser en el bot贸n:

<button
                onClick={() => {
                    setError(false)
                    setLoading(!loading)
                    }
                }
            >Comprobar</button>

Otra, antes de setTimeout:

 if (!!loading) {
            setError(false);
            setTimeout(() => {
                console.log("Haciendo la validacion")

                if(value !== SECURITY_CODE) {
                    setError(true);
                }

                setLoading(false);

                console.log("Terminando la Validacion")
            }, 3000)
        }

y otra que se me ocurri贸 es en el input, teniendo en cuenta que se borra apenas tecleen en el, pero si no borran el anterior texto no se quitar铆a el mansaje de error:

<input
                placeholder="Codigo de seguridad"
                value={value}
                onChange={(event) => {
                    setValue(event.target.value);
                    setError(false);
                }}
            />