我正在学习一个关于react的教程,并且正在创建一个登录页面。当用户完成写邮件时,我们调用onBlur()。正如你在第120行看到的,onBlur在第8行调用了emailReducer,在那里运行了includes()命令。
然而,当我在第11行和第14行使用include()命令时,我总是得到这个错误消息(如本文标题所示)。我console.logged了第11行中的action.瓦尔值,它确实存在。
我觉得这是个时间问题。有人知道如何解决这个问题吗?谢谢!
import React, { useState, useEffect, useReducer } from 'react';
import Card from '../UI/Card/Card';
import classes from './Login.module.css';
import Button from '../UI/Button/Button';
// made outside the component function: doesnt use any props defined inside the function
const emailReducer = (state, action) => {
if (action.type === 'USER_INPUT') {
console.log(action.val);
return { value: action.val, isValid: action.val.includes('@') };
}
if (action.type === 'INPUT_BLUR') {
return { value: state.value, isValid: action.value.includes('@') };
}
return { value: '', isValid: false };
};
const passwordReducer = (state, action) => {
if (action.type === 'USER_INPUT') {
return { value: action.val, isValid: action.val.trim().length > 6 };
}
if (action.type === 'INPUT_BLUR') {
return { value: state.value, isValid: action.value.trim().length > 6 };
}
return { value: '', isValid: false };
}
const Login = (props) => {
// const [enteredEmail, setEnteredEmail] = useState('');
// const [emailIsValid, setEmailIsValid] = useState();
// const [enteredPassword, setEnteredPassword] = useState('');
// const [passwordIsValid, setPasswordIsValid] = useState();
const [formIsValid, setFormIsValid] = useState(false);
const [emailState, dispatchEmail] = useReducer(emailReducer, {
value: '',
isValid: null,
});
const [passwordState, dispatchPassword] = useReducer(passwordReducer, {
value: '',
isValid: null,
})
useEffect(() => {
console.log('EFFECT RUNNING');
return () => {
console.log('EFFECT CLEANUP');
};
}, [])
// useEffect(() => {
// // start the Timer
// const identifier = setTimeout(() => {
// setFormIsValid(
// emailState.value.includes('@') && enteredPassword.trim().length > 6
// );
// console.log('okay im pretty sure ur done');
// }, 500);
// // can return, but MUST be a function = Called a CLEAN UP function
// // clean up fucntions ALWAYS run first before all other code in UseEffect
// return () => {
// // reset the Timer IF change was made
// console.log('CLEAN UP FUNCTION: reset timer')
// clearTimeout(identifier);
// };
// }, [enteredEmail, enteredPassword]);
const emailChangeHandler = (event) => {
dispatchEmail({ type: 'USER_INPUT', val: event.target.value});
setFormIsValid(
event.target.value.includes('@') && passwordState.isValid
);
};
const passwordChangeHandler = (event) => {
dispatchPassword({ type: 'USER_INPUT', val: event.target.value});
setFormIsValid(
emailState.isValid && event.target.value.trim().length > 6
);
};
const validateEmailHandler = () => {
// setEmailIsValid(emailState.isValid);
dispatchEmail({type: 'INPUT_BLUR'});
};
const validatePasswordHandler = () => {
dispatchPassword({type: 'INPUT_BLUR'})
};
const submitHandler = (event) => {
event.preventDefault();
props.onLogin(emailState.value, passwordState.value);
};
return (
<Card className={classes.login}>
<form onSubmit={submitHandler}>
<div
className={`${classes.control} ${
emailState.isValid === false ? classes.invalid : ''
}`}
>
<label htmlFor="email">E-Mail</label>
<input
type="email"
id="email"
value={emailState.value}
onChange={emailChangeHandler}
onBlur={validateEmailHandler}
/>
</div>
<div
className={`${classes.control} ${
passwordState.isValid === false ? classes.invalid : ''
}`}
>
<label htmlFor="password">Password</label>
<input
type="password"
id="password"
value={passwordState.value}
onChange={passwordChangeHandler}
onBlur={validatePasswordHandler}
/>
</div>
<div className={classes.actions}>
<Button type="submit" className={classes.btn} disabled={!formIsValid}>
Login
</Button>
</div>
</form>
</Card>
);
};
export default Login;
1条答案
按热度按时间83qze16e1#
分派的
onBlur
操作没有有效负载:但是reducer函数需要一个
value
payload属性:我怀疑您的意思是在留下输入时只验证现有状态,为此您应该引用
state.value
而不是action.value
。示例: