skip to Main Content

I want to render login and registration link on my header when user is not logged-in and logout link when user is logged-in.
I make a state for storing the status of user login status and calling dispatch function before logout and login.
Every thing is working fine in my reducer and action I checked by printing on console but when we getting value of store at console it not showing the updated value.

import React, { useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom';
import Footer from '../footer/Footer';
import "./Login.css";
import { setUser } from '../../actions/index';
import { useDispatch } from 'react-redux';
import store  from '../../store';

const Login = () => {
  const state = store.getState();
  const userdata = Object.values(state);
   
  const sendUserstatus = useDispatch();

  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  const handleEmailChange = (event) => {
    setEmail(event.target.value);
  }

  const handlePasswordChange = (event) => {
    setPassword(event.target.value);
  }

  const navigate = useNavigate();

  const handleSubmit = async (event) => {
    event.preventDefault();
    const res = await fetch("/signin", {
      method: "POST",
      headers: {
        "content-Type": "application/json"
      },
      body: JSON.stringify({
        email,
        password
      })
    })
    const data = res.json();
    if (res.status === 400 || !data) {
      window.alert("invalid Credentials");
    } else {
      sendUserstatus(setUser(true));
      console.log(userdata, "login successful");

      window.alert("Login Successful");
      navigate("/")
    }
  }
  return (
    <>
      <form method='POST' onSubmit={handleSubmit} className="login-form">
        <label className="login-label">
          Email:
          <input
            type="email"
            value={email}
            onChange={handleEmailChange}
            className="login-input"
          />
        </label>
        <br />
        <label className="login-label">
          Password:
          <input
            type="password"
            value={password}
            onChange={handlePasswordChange}
            className="login-input"
          />
        </label>
        <br />
        <a href="#sfsd" className="forgot-password-link">Forgot password?</a>
        <br />
        <button type="submit" className="login-button">Login</button>
      </form>
      <Footer></Footer>
    </>
  )
}

export default Login

Here in this code before user login successful I called dispatch but on my console data remain same.

this is my reducer

const initialdata = false;

export const truefalse = (state = initialdata, action) => {
  switch(action.type) {
    case "SET_TRUE":
      return state = true;

    case "SET_FALSE":
      return state = false;

    default:
      return state;
  }
}

var wpmdata = 0;

export const setWpm = (state = wpmdata, action) => {
  switch(action.type) {
    case"SET_WPM":
      return wpmdata = action.paylod;

    default:
      return wpmdata;
  }
}

var Accuracy = 0;

export const setAccuracy = (state = Accuracy, action) => {
  switch(action.type) {
    case"SET_ACCURACY":
      return Accuracy = action.Accuracy;

    default:
      return Accuracy;
  }
}

var userStatus = null;

export const setUser = (state = userStatus, action) => {
  switch(action.type){
    case "SET_USER":
      return userStatus = action.userStatus;

    default: return userStatus;
  }
}

var Toggle = null;

export const setToggle = (state = Toggle, action) => {
  switch(action.type) {
    case "TOGGLE":
      return Toggle = action.Toggle

    default:
      return Toggle
  }
}

This is my actions ———–

export const setTrue = () => {
  return {
    type: "SET_TRUE",
  }
}

export const setFalse = () => {
  return {
    type: "SET_FALSE",
  }
}

export const setWpm = (val) => {
  return {
    type: "SET_WPM",
    paylod: val
  }
}

export const setAccuracy = (val) => {
  return {
    type: "SET_ACCURACY",
    Accuracy: val
  }
}

export const setUser = (val) => {
  console.log(val, "afsdf");
  return {
    type: "SET_USER",
    userStatus: val
  }
}

export const setToggle = (val) => {
  return {
    type: "TOGGLE",
    Toggle: val
  }
}
import {
  truefalse,
  setAccuracy,
  setWpm,
  setUser,
  setToggle
} from "./typingtestReducer";
import { combineReducers } from "redux";

const rootReducer = combineReducers({
  truefalse,
  setWpm,
  setAccuracy,
  setUser,
  setToggle
})

export default rootReducer

I tried to debug by printing every breakpoint value which is sending true or false and it working in reducer and action payload etc.

When we try to print value of store userStatus at console its remain same.

I want to make toggle sigin and sign in using react redux.

2

Answers


  1. try to change

    const state=store.getState();
    

    to :

    const state= useSelector(state=>state);
    

    for getting state value from react-redux we need to useSelector hook

    Login or Signup to reply.
  2. userdata will have the value it has from the render cycle it was selected in closed over in the handleSubmit callback scope. It will never update during the life of the callback. In other words, this is an issue of a stale closure over the userdata variable.

    If you want to access the current value from the store you can call store.getState again in the callback scope.

    const handleSubmit = async (event) => {
      event.preventDefault();
      const res = await fetch("/signin", {
          method: "POST",
          headers: {
            "content-Type": "application/json"
          },
          body: JSON.stringify({ email, password }
        )
      })
      const data = res.json();
      if (res.status === 400 || !data) {
        window.alert("invalid Credentials");
      } else {
        sendUserstatus(setUser(true));
        const state = store.getState();
        const userdata = Object.values(state);
        console.log(userdata, "login successful");
    
        window.alert("Login Successful");
        navigate("/")
      }
    }
    

    The normal React convention to log state updates is to use a useEffect hook with the state value as a dependency.

    useEffect(() => {
      console.log({ userdata });
    }, [userdata]);
    

    Additionally, calling store.getState() isn’t how a React component subscribes to a Redux store. Use the useSelector hook to subscribe the component to store changes.

    Example:

    import { useSelector } from 'react-redux';
    
    ...
    
    const Login = () => {
      const userdata = useSelector(state => Object.values(state));
    
      ...
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search