I am trying to figure out how I can use the state value from a hook in a function. At the moment, I am able to use the value when the component is returned, but within my function it is appearing as undefined
. Is there a limit to the scope of where state values can be accessed? I am trying to use this value as a workaround to the limitation in passing values down promise chains so I can check if a redirect should be triggered
Undefined line:
console.log(message) // undefined
Function where message
is accessed:
const signIn = (e) => {
e.preventDefault();
console.log('Axios: signIn Triggered')
axios.post('/api/auth/signin/', { email, password }, {
headers: {
'Content-Type': 'application/json'
},
withCredentials: true
}).then((res) => {
console.log('Success - res')
console.log(res)
const data = res.data;
console.log(data.message)
console.log(data.user)
console.log(message)
// Set user session state with returned user data
setUser(data.user)
setMessage(data.message)
}).then(()=> {
// On successful sigin, redirect to /app/profile/
console.log(message) // returns `undefined`
// if (message.status !== 'error'){
// router.push('/app/profile/')
// }
}).catch((err) => {
console.log(err)
console.log(err.request)
console.log(err.message)
})
}
Full Code:
import axios from 'axios';
import React, { useContext, useEffect, useState } from 'react'
import { useRouter } from 'next/router'
import { SessionContext } from '../../../contexts/AppSession'
const SignInForm = () => {
const [{ email, password }, setForm] = useState({ email: null, password: null })
const [message, setMessage] = useState()
const { user, setUser } = useContext(SessionContext) // here you are calling a hook at component body
const router = useRouter()
const handleChange = ({ target }) => {
setForm( prevForm => ({
...prevForm,
[target.name]: target.value
}));
}
const signIn = (e) => {
e.preventDefault();
console.log('Axios: signIn Triggered')
axios.post('/api/auth/signin/', { email, password }, {
headers: {
'Content-Type': 'application/json'
},
withCredentials: true
}).then((res) => {
console.log('Success - res')
console.log(res)
const data = res.data;
console.log(data.message)
console.log(data.user)
console.log(message)
// Set user session state with returned user data
setUser(data.user)
setMessage(data.message)
}).then(()=> {
// On successful sigin, redirect to /app/profile/
console.log(message)
// if (message.status !== 'error'){
// router.push('/app/profile/')
// }
}).catch((err) => {
console.log(err)
console.log(err.request)
console.log(err.message)
})
}
useEffect(() => {
console.log(user)
}, [user]) // with that console.log will run on every user change
return (
<div className="signup-form">
<div className="grid min-h-screen place-items-center">
<div className="w-11/12 p-12 bg-white sm:w-8/12 md:w-1/2 lg:w-5/12">
<h1 className="text-xl font-semibold">Hello there ??, <span className="font-normal">please fill in your information to continue</span></h1>
<form className="mt-6" action="/api/auth/signin/" method="post">
<label htmlFor="email" className="block mt-2 text-xs font-semibold text-gray-600 uppercase">E-mail</label>
<input id="email" type="email" name="email" placeholder="[email protected]" autoComplete="email" className="block w-full p-3 mt-2 text-gray-700 bg-gray-200 appearance-none focus:outline-none focus:bg-gray-300 focus:shadow-inner" value={ email || '' } onChange={ handleChange } required />
<label htmlFor="password" className="block mt-2 text-xs font-semibold text-gray-600 uppercase">Password</label>
<input id="password" type="password" name="password" placeholder="********" autoComplete="new-password" className="block w-full p-3 mt-2 text-gray-700 bg-gray-200 appearance-none focus:outline-none focus:bg-gray-300 focus:shadow-inner" value={ password || '' } onChange={ handleChange } required />
<button type="submit" className="w-full py-3 mt-6 font-medium tracking-widest text-white uppercase bg-black shadow-lg focus:outline-none hover:bg-gray-900 hover:shadow-none" onClick={ signIn }>
Sign In
</button>
{message ?
<div className="bg-red-200 px-6 py-4 my-4 rounded-md text-lg flex items-center w-full">
<svg viewBox="0 0 24 24" className="text-red-600 w-10 h-10 sm:w-5 sm:h-5 mr-3">
<path fill="currentColor" d="M11.983,0a12.206,12.206,0,0,0-8.51,3.653A11.8,11.8,0,0,0,0,12.207,11.779,11.779,0,0,0,11.8,24h.214A12.111,12.111,0,0,0,24,11.791h0A11.766,11.766,0,0,0,11.983,0ZM10.5,16.542a1.476,1.476,0,0,1,1.449-1.53h.027a1.527,1.527,0,0,1,1.523,1.47,1.475,1.475,0,0,1-1.449,1.53h-.027A1.529,1.529,0,0,1,10.5,16.542ZM11,12.5v-6a1,1,0,0,1,2,0v6a1,1,0,1,1-2,0Z"></path>
</svg>
<span class="text-red-800">{ message.body }</span>
</div>
: null
}
</form>
</div>
</div>
</div>
)
}
export default SignInForm;
question from:
https://stackoverflow.com/questions/65540991/using-hook-value-in-promise-chain