A煤n no tienes acceso a esta clase

Crea una cuenta y contin煤a viendo este curso

Estados independientes con useState

6/19
Recursos

Aportes 44

Preguntas 0

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad? Crea una cuenta 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)
    }

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)}
      />

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>
)}

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])
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])

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);
                }}
            />