0
votes

I want to go through an array and check if it matches value with the values of name in array or not and change setFound value to true if it (if it matches and false if it not matches) But it keeps on changing state. i called function changeState in if condition to change state if it matches. First thing is that it does not check all the values in array and Second it keeps on changing state.

import React from 'react';

import { Paper, Typography, TextField , Button, makeStyles} from '@material-ui/core';

import { Link} from 'react-router-dom'

import {useEffect} from 'react';

const useStyle = makeStyles((theme)=>(

{
    formWrapper : {
        display : 'flex',
        width : '100%',
        height : '100%',
        alignItems : 'center',
        justifyContent : 'center'
    },
    paper : {
        padding : '20px',
        margin : '20px'
    },
    textfield : {
        marginLeft : '20px',
        marginBottom : '10px'
    },
    span : {
        margin: '10px',
        marginLeft : '20px'
    }

}

))

const Register = () =>{

const classes = useStyle();
const [name, setName] = React.useState('');
const [password, setPassword] = React.useState('');
const [array, setArray] = React.useState([{name : 'faateh', password : 'pass'},{name : 'Yousaf', password : 'pass'}])
const [found, setFound] =  React.useState(false);

useEffect(()=>{localStorage.setItem('array',JSON.stringify(array))},[array])

 const changeState = async() =>{
     await setFound(current => !current)
}

const submit = (event) =>{
    const obj = {}
    event.preventDefault();
    if(array.length === 0){ // Array is empty
        if((name === null || password === null)||(name === '' || password === '')){ //check if name and password are empty
            alert('Enter username and password')
            
        }else{  // not empty then store in localstorage
            localStorage.setItem('name', name);
            localStorage.setItem('password',password);
            obj.id = Math.random();
            obj.name = localStorage.getItem('name');
            obj.password = localStorage.getItem('password');
            setArray(array => [...array,obj])
            setName('');
            setPassword('')
            return alert('You are registered'); 
            
        }
    }
    else  // array not empty
    {
        for( let i = 0; i < array.length ; i++){
            if((name === null || password === null)||(name === '' || password === '')){ //check if name and password is empty
               return alert('Enter username and password')
            }else if(name === array[i].name){ // if it is matched then setFound is set to true
                 changeState();
            }
        }
        if(found){
           return alert('it is matched')
        }else{
            return alert('it is not found')
        }
    }}

return(
    <div>
        <div className = {classes.formWrapper}>
            <Paper elevation={3} className = {classes.paper} >
            <Typography variant="h5" style = {{ textAlign : 'center'}}>Register</Typography>
            <form noValidate autoComplete="off">
                <TextField id="username" className={classes.textfield}  value = {name} name = "username"  label="Username" onChange = {e=>setName(e.target.value)} />
                <br />
                <TextField id="password" className={classes.textfield}  value = {password} name = "password"  label="Password" onChange = {e=>setPassword(e.target.value)} />
                <br />
                <span className ={classes.span}><Link to="/">Sign In</Link></span>
                <br />
                <Button variant="contained" color="secondary" style = {{width : '100%', marginTop : '10px'}} onClick = {submit} >Register </Button>
            </form>
            </Paper>
        </div>
    </div>

)

}

export default Register;

1

1 Answers

1
votes

Firstly there is no point to call await setFound(current => !current) because state update will run async anyway and there is no way to wait for state update using hooks unless you write your custom hook. You could use callback in old setState way. More info on the link below.

https://ysfaran.github.io/blog/post/0002-use-state-with-promise/

Secondly, your logic in submit method isn't right. I believe you are trying to register user and you want to make sure that new user name is unique and it doesn't exist in the array which is list of user objects. If that's the case you can update your logic in submit method as following.

const submit = (event) => {
    const obj = {};
    event.preventDefault();
    // Array is empty
    if (name === null || password === null || name === "" || password === "") {
      //check if name and password are empty
      alert("Enter username and password");
    } 
    else {
      if (array.some((x) => x.name === name)) alert("user already exists");
      else {
        // not empty then store in localstorage
        localStorage.setItem("name", name);
        localStorage.setItem("password", password);
        obj.id = Math.random();
        obj.name = localStorage.getItem("name");
        obj.password = localStorage.getItem("password");
        setArray((array) => [...array, obj]);
        setName("");
        setPassword("");
        alert("successfully registred");
      }
    }
  };

So first if statement will ensure that name and password are provided. Then in else statement first if check will ensure that user with same name doesn't already exist in the array. You can call changeState instead of alert if you prefer but I am not sure what exactly you are trying to achive by setting setFound to either true or false.