我正在使用
useReducer
作为我的登录/注册表格。
当我使用记录reducer值时,它只返回默认值,而当我在useEffect钩子上记录它时,它可以完美地工作。
这是我的代码的一小部分:
//reducer
function reducer(state: State, action: Action): State {
switch (action.type) {
case "SET_EMAIL":
return { ...state, email: action.payload };
case "SET_NAME":
return { ...state, name: action.payload };
default:
return state;
}
}
// load reducer
const [state, dispatch] = useReducer(reducer, { email: "" });
//elements:
const registerElements: Elements[] = [
{
type: "text",
name: "name",
placeholder: "name",
onChange: (e) => dispatch({ type: "SET_NAME", payload: e.target.value }),
value: state.name || "",
},
{
type: "email",
name: "email",
placeholder: "email",
onChange: (e) => dispatch({ type: "SET_EMAIL", payload: e.target.value }),
value: state.email || "",
},
];
//functions
function onSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
if (!recaptchaLoaded) return;
window.grecaptcha.execute();
}
//Works perfectly fine, valid function is called
function scriptLoadReCAPTCHA() {
setRecaptchaLoaded(true);
window.grecaptcha.ready(() => {
window.grecaptcha.render("recaptcha", {
sitekey: process.env.NEXT_PUBLIC_RECAPTCHA_SITEKEY,
callback: action === "signin" ? signin : signup,
size: "invisible",
});
});
}
// Signup. I'm currently testing with signup only.
function signup(token: string) {
console.log(state);//output: {email: ''}
fetch("/api/login/signup", {
method: "POST",
headers: {
"Content-Type": "application/json",
recaptcha: token,
},
body: JSON.stringify(state),
})
.then((res) => res.json())
.then(console.log);
}
//input
<form className="my-8 flex flex-col gap-4" onSubmit={onSubmit}>
{(action === "signin" ? loginElements : registerElements).map(
(loginElement) => (
<input
required
key={loginElement.name}
type={loginElement.type}
name={loginElement.name}
placeholder={loginElement.placeholder}
onChange={loginElement.onChange}
value={loginElement.value}
className="w-full border-b-2 border-white bg-transparent px-0 py-1 capitalize text-white transition placeholder:text-gray-200 focus-visible:border-b-yellow focus-visible:outline-none"
/>
),
)}
...
</form>
当我
console.log
打开submit
时,它保持默认值。
但是,当我像这样使用
useEffect
时:
useEffect(() => {
console.log(state);
}, [state]);
它正在记录输入中的值
我可以做什么来解决这个问题?
我编辑了我的函数来解决这个问题:
function onSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
if (!recaptchaReady) return;
console.log("executed");
if(!recaptchaRendered){
window.grecaptcha.render("recaptcha", {
sitekey: process.env.NEXT_PUBLIC_RECAPTCHA_SITEKEY,
callback: action === "signin" ? signin : signup,
size: "invisible",
});
setRecaptchaRendered(true);
} else {
window.grecaptcha.reset()
}
window.grecaptcha.execute()
}