I’m using react redux for the signup and sign in of my react project. When a user signs in I want it to navigate to the profile page, or if there is an error, display the error. It works for the signup page but for some reason not for the sign in. The code is nearly identical so I don’t understand why it’s happening. I am a beginner to this sort of thing so I don’t really know how to bug fix it.
main.jsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import "./index.css"
import axios from 'axios'
import { store } from './store/store.jsx'
import { Provider } from 'react-redux'
import { createBrowserRouter, createRoutesFromElements, Route, RouterProvider } from 'react-router-dom'
import SignupForm from './Components/signup'
import SigninForm from './Components/signin'
import RootLayout from './Components/root-layout'
import ErrorPage from './Components/error-page'
import ProfilePage from './Components/profile'
const router = createBrowserRouter(
createRoutesFromElements((
<Route path='/' element={<RootLayout />}>
<Route path='/' element={<App />}></ Route>
<Route path='/signup' element={<SignupForm />} ></Route>
<Route path='/signin' element={<SigninForm />} ></Route>
<Route path='*' element={<ErrorPage />}></Route>
<Route path='/profile' element={<ProfilePage />}></Route>
</Route>
)
))
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<Provider store={store}>
<RouterProvider router={router} />
</Provider>
</React.StrictMode>,
)
store.jsx
import { configureStore } from '@reduxjs/toolkit'
import authSlice from './authSlice'
export const store = configureStore({
reducer: {
auth: authSlice
}
})
authSlice.jsx
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import axios from "axios";
export const signup = createAsyncThunk('auth/signup', async({username, password}, thunkAPI) => {
try {
const res = await axios.post('http://localhost:8080/signup', {username, password})
return res.data
} catch (err) {
console.log(err)
return thunkAPI.rejectWithValue(err.message)
}
})
export const signin = createAsyncThunk('auth/signin', async({username, password}) => {
try {
const res = await axios.post('http://localhost:8080/signin', {username, password})
return res.data
} catch (err) {
return thunkAPI.rejectWithValue(err.response.data)
}
})
const initialState = {
user: '',
isLoggedIn: false,
loading: false,
error:null
}
export const authSlice = createSlice({
name: 'auth',
initialState,
reducers: {
logout: (state, action) => {
state.user = ''
state.isLoggedIn = false
state.loading = false
state.error = null
}
},
extraReducers: (builder) => {
builder
.addCase(signup.fulfilled, (state, action) => {
state.user = action.payload.username
state.isLoggedIn = true
state.loading = false
state.error = null
})
.addCase(signup.pending, (state, action) => {
state.loading = true
})
.addCase(signup.rejected, (state, action) => {
state.loading = false
state.isLoggedIn = false
state.error = action.payload
})
.addCase(signin.fulfilled, (state, action) => {
state.user = action.payload.username
state.isLoggedIn = true
state.loading = false
state.error = null
})
.addCase(signin.pending, (state, action) => {
state.loading = true
})
.addCase(signin.rejected, (state, action) => {
state.loading = false
state.isLoggedIn = false
state.error = action.payload
})
}
})
export const { logout } = authSlice.actions
export default authSlice.reducer
profile.jsx
import { useSelector } from "react-redux"
export default function ProfilePage () {
const user = useSelector((state) => state.auth.user) //This useSelector works properly for some reason
return (
<div>
<h3>Profile</h3>
{user ? <div>Hi, {user}!</div> : null}
</div>
)
}
signup.jsx
import { useDispatch, useSelector } from "react-redux";
import { Navigate } from "react-router-dom";
import { signup } from "../store/authSlice";
export default function SignupForm () {
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const user = useSelector((state) => state.auth.user)
const error = useSelector((state) => state.auth.error)
//These two useSelectors appear to not work when I console.log but the code still runs normally
const dispatch = useDispatch()
const submitHandler = e => {
e.preventDefault()
dispatch(signup({username, password}))
.then((res) => {
setPassword('')
setUsername('')
})
console.log(user)
console.log(error)
}
return (
<div>
<form onSubmit={submitHandler}>
<div>Sign up</div>
<div>
<label htmlFor="username">Username:</label>
<input id="username" type="text" value={username} onChange={(e) => setUsername(e.target.value)} minLength={1} maxLength={60}/>
</div>
<div>
<label htmlFor="password">Password:</label>
<input id="password" type="password" value={password} onChange={(e) => setPassword(e.target.value)} minLength={1}/>
</div>
<div>
<button>Cancel</button>
<button type="submit">Submit</button>
</div>
{error ? <p>{error}</p> : null}
{user ? <Navigate to='/profile' replace={true} /> : null}
</form>
</div>
)
}
signin.jsx
import React, { useState } from "react";
import { ReactDOM } from "react";
import { useDispatch, useSelector } from "react-redux";
import { Navigate } from "react-router-dom";
import { signin } from "../store/authSlice";
export default function SigninForm () {
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const user = useSelector((state) => state.auth.user)
const error = useSelector((state) => state.auth.error)
//These are the two not working ^
const dispatch = useDispatch()
const submitHandler = e => {
e.preventDefault()
dispatch(signin({username, password}))
.then((res) => {
setPassword('')
setUsername('')
})
console.log(user)
console.log(error)
}
return (
<div>
<form onSubmit={submitHandler}>
<div>Sign in</div>
<div>
<label htmlFor="username">Username:</label>
<input id="username" type="text" value={username} onChange={(e) => setUsername(e.target.value)} minLength={1} maxLength={60}/>
</div>
<div>
<label htmlFor="password">Password:</label>
<input id="password" type="password" value={password} onChange={(e) => setPassword(e.target.value)} minLength={1}/>
</div>
<div>
<button>Cancel</button>
<button type="submit">Submit</button>
</div>
{error ? <div>{error}</div> : null}
{user ? <Navigate to='/profile' replace={true} /> : null}
//This is where the real issue is. These two ^ are not running even though it runs on the signup page
</form>
</div>
)
}
Sorry if this is a bit long. Any help would be appreciated
This is what the console.logs on the signin page return:
console
console.log showed me that the useSelectors were not running correctly. Do not really know how to try and fix them as the ones on the profile page run normally with the exact same code.
Cian Neiland is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.