Skip to content

Instantly share code, notes, and snippets.

@JinsupJung
Created April 22, 2023 06:33
Show Gist options
  • Select an option

  • Save JinsupJung/081d36d7382b8904af51aefbd1a99567 to your computer and use it in GitHub Desktop.

Select an option

Save JinsupJung/081d36d7382b8904af51aefbd1a99567 to your computer and use it in GitHub Desktop.
[리액트 Input forwardRef] #React
import React, { useRef, useImperativeHandle } from 'react';
import classes from './Input.module.css';
const Input = React.forwardRef((props, ref) => {
const inputRef = useRef();
const activate = () => {
inputRef.current.focus();
};
useImperativeHandle(ref, () => {
return {
focus: activate,
};
});
return (
<div
className={`${classes.control} ${
props.isValid === false ? classes.invalid : ''
}`}
>
<label htmlFor={props.id}>{props.label}</label>
<input
ref={inputRef}
type={props.type}
id={props.id}
value={props.value}
onChange={props.onChange}
onBlur={props.onBlur}
/>
</div>
);
});
export default Input;
import React, {
useState,
useEffect,
useReducer,
useContext,
useRef,
} from 'react';
import Card from '../UI/Card/Card';
import Button from '../UI/Button/Button';
import AuthContext from '../../store/auth-context';
import Input from '../UI/Input/Input';
import classes from './Login.module.css';
const emailReducer = (state, action) => {
if (action.type === 'USER_INPUT') {
return { value: action.val, isValid: action.val.includes('@') };
}
if (action.type === 'INPUT_BLUR') {
return { value: state.value, isValid: state.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: state.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,
});
const authCtx = useContext(AuthContext);
const emailInputRef = useRef();
const passwordInputRef = useRef();
useEffect(() => {
console.log('EFFECT RUNNING');
return () => {
console.log('EFFECT CLEANUP');
};
}, []);
const { isValid: emailIsValid } = emailState;
const { isValid: passwordIsValid } = passwordState;
useEffect(() => {
const identifier = setTimeout(() => {
console.log('Checking form validity!');
setFormIsValid(emailIsValid && passwordIsValid);
}, 500);
return () => {
console.log('CLEANUP');
clearTimeout(identifier);
};
}, [emailIsValid, passwordIsValid]);
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 = () => {
dispatchEmail({ type: 'INPUT_BLUR' });
};
const validatePasswordHandler = () => {
dispatchPassword({ type: 'INPUT_BLUR' });
};
const submitHandler = (event) => {
event.preventDefault();
if (formIsValid) {
authCtx.onLogin(emailState.value, passwordState.value);
} else if (!emailIsValid) {
emailInputRef.current.focus();
} else {
passwordInputRef.current.focus();
}
};
return (
<Card className={classes.login}>
<form onSubmit={submitHandler}>
<Input
ref={emailInputRef}
id="email"
label="E-Mail"
type="email"
isValid={emailIsValid}
value={emailState.value}
onChange={emailChangeHandler}
onBlur={validateEmailHandler}
/>
<Input
ref={passwordInputRef}
id="password"
label="Password"
type="password"
isValid={passwordIsValid}
value={passwordState.value}
onChange={passwordChangeHandler}
onBlur={validatePasswordHandler}
/>
<div className={classes.actions}>
<Button type="submit" className={classes.btn}>
Login
</Button>
</div>
</form>
</Card>
);
};
export default Login;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment