Home > Back-end >  React not writing all values from localStorage to useState
React not writing all values from localStorage to useState

Time:06-18

I have an application in which you can register and log in. I store all users in useState, which is located in App.js (initially there are three users). If a new user registers, then I store his data in localStorage, so that when the application is restarted, they would be in my UseState App.js, this is the problem. If you work in one session, then everything works well: After registrations, I can easily log into a new account, regardless of how many I have created (Data is written correctly in localStorage), but as soon as I restart the application, then in my App.js from localStorage only one LAST object from localStorage comes in, although if I display the actions of my useEffect in the console, then From localStorage, all users are moved one by one, and as a result, only the last user is added to useState, can you tell me what could be the problem?

Here code: App.js (Error in useEffect i think)

import React, {useState, useEffect} from 'react';
import './App.css';

import {Routes, Route} from 'react-router-dom'


import Registr from './components/AuthPage/Registr';
import Login from './components/AuthPage/Login';

function App() {

  const [activeUser, setActiveUser] = useState();
  const [realUsers, setRealUsers] = useState([]); 
  const [users, setUsers] = useState(
    [
      {
        id: 0,
        name: 'Andrey',
        email: '[email protected]',
        password: 'qwerty'
      },

      {
        id: 1,
        name: 'Roma',
        email: '[email protected]',
        password: '123'
      },
      {
        id: 2,
        name: 'Ilya',
        email: '[email protected]',
        password: 'zxc'
      }
    ]
  )

  useEffect(() => {

      for (let i = 0; i < localStorage.length; i  ) {   //
        
        const userKey = localStorage.key(i); //find user key name
        const JSONUserFromLocalStorage = localStorage.getItem(userKey);

        const parsedUser = JSON.parse(JSONUserFromLocalStorage);  
    
        setUsers([...users, parsedUser])    

    }
  }, []); 

  return (
    <>
            <Routes>
                <Route path = '/' element = {<Login users = {users} setActiveUser = {setActiveUser}/>}></Route> 
                <Route path = '/registration' element = {<Registr users = {users} setUsers = {setUsers}/>}></Route>
            </Routes>
    </>
  );
}

export default App;

Login.js

import React, {useReducer, useState} from 'react';
import closedEye from '../icons/closedEye.png';
import openedEye from '../icons/openedEye.png';
import warning from '../icons/warning.png';
import './Login.css';

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

function Login({users, setActiveUser}){        

    const [anError, setStatus] = useState()
        
    const [isPrivate, setPrivate] = useState(true); 
    let typeOfEye = isPrivate ? closedEye : openedEye;
    let typeOfInput = isPrivate ? 'password' : 'text';


    const [form, setForm] = useState({     
        email: '',
        password: ''
    }); 
    const changeHandler = (e) => {
        setForm({...form, [e.target.name] : e.target.value});
    }


    const checkForValidate = () =>{
        const {email, password} = form;

        if (email.length === 0){
            setStatus(
                <div className='error-block'><img src = {warning} alt = 'warning'></img><p className='error'>Enter your email</p></div>
            );   
            return 
        }else{
            setStatus()
        }
        if (password.length === 0){
            setStatus(
                <div className='error-block'><img src = {warning} alt = 'warning'></img><p className='error'>Enter your password</p></div>
            );   
            return
        }else{
            setStatus()
        }
        //Checking if a user exists in the database by email

        const doesEmailValid = users.find(user => user.email === email)

        if(!doesEmailValid){        //doesEmailValid the user object we found by email            setStatus(
                <div className='error-block'><img src = {warning} alt = 'warning'></img><p className='error'>Uncorrect email</p></div>
            );   
            return
        }else{  
            setStatus()
        }
        if (doesEmailValid.password !== password){     
            setStatus(
                <div className='error-block'><img src = {warning} alt = 'warning'></img><p className='error'>Uncorrect password</p></div>
               
            );
        }else{  //If everything is alright:
            setStatus(<p className='succes'>User successfully authorized</p>);
            setActiveUser(doesEmailValid);
        }   
    }
    return (
        <div className='login-wrapper'>
            <div className = 'login'>
            <h3>authorize</h3>
            {anError}
            <form
            onSubmit={(e) => e.preventDefault()}>
                <div className='form'>
                    <div className='inputs'>
                        <div className='email-field'>
                            <label htmlFor='email'>Email</label>
                            <input 
                            type = 'email'
                            name = 'email'
                            onChange = {changeHandler}
                            >   
                            </input>
                            
                        </div>
                        
                        <div className='password-field'>
                            <label htmlFor='email'>Password</label>
                            <div className='row'>
                                <input 
                                type = {typeOfInput}
                                name = 'password'
                                maxLength={14}
                                onChange = {changeHandler}
                                >   
                                </input>
                                {/* <img src = {require('./closedEye.png')}></img> */}
                                <img 
                                src = {typeOfEye} alt = 'eye'
                                onClick={()=> {setPrivate(!isPrivate)}}
                                ></img> 
                            </div>
                        </div>
                    </div>
                    <div className='login-buttons'>
                        <button 
                        type = 'submit'
                        onClick={checkForValidate}
                        >Enter</button>
                        <Link to = '/registration'>No account?</Link>
                    </div>
                </div>
            </form>
        </div>
        </div>
    )
};

export default Login;

If we created one account in the LAST session, then authorization is successful. If we have created several accounts, then we can only log in to the LAST created one, otherwise my error comes out: Uncorrect email

CodePudding user response:

This doesn't answer your question, but I want to call out a security issue with your code. It looks like you're storing passwords in the database, which you should never do. You also shouldn't store them in local storage.

You want to store a password hash in the database, and hash the password every time on login to check if it's the correct password. See here for some more info.

CodePudding user response:

Quickly looking at your code it seems that setUsers([...users, parsedUser]) is going to be an issue. React does batch setState updates every 10ms or so, which means that your entire loop will have executed over and over before it ever actually sets the state. That's why it will only set the last item that was ever called before the state update happens.

Instead do something like:

users.push(JSON.parse(// user))

Then:

setUsers(users)

So you can set all of them at once.

  • Related