在promise链中使用hook值



我正试图弄清楚如何在函数中使用钩子中的状态值。目前,我可以在返回组件时使用该值,但在我的函数中,它显示为undefined。可以访问状态值的范围是否有限制?我正试图使用这个值作为一种变通方法,以解决将值传递到承诺链的限制,这样我就可以检查是否应该触发重定向

未定义的行:

console.log(message) // undefined

访问message的功能:

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)
})
}

完整代码:

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="john.doe@company.com" 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;

不要忘记,箭头函数总是在创建函数的那一刻记住值。。。因此,在一开始,您的message值是undefined,在组件被重新发送之前,它将保持未定义状态,所以当您调用setMessage时,它根本不会影响消息值,它只会发出一个命令来响应您想要更改状态。。。

因此,如果您想在setMessage(data.message)之后的下一个then块中看到新值,只需返回data.message并将其作为下一个块中的参数读取即可

setMessage(data.message)
return data.message
}).then(newMessage => {
// On successful sigin, redirect to /app/profile/
console.log(newMessage)

最新更新