반응형
input div를 포함하는 컴포넌트 파일을 하나 생성하겠다
props를 통해 모든 데이터를 받는 컴포넌트다
버튼처럼 재사용 가능하게 만들 것이다
Input.js
import React from 'react';
import classes from './input.module.css';
const Input = (props) => {
return <div
className={`${classes.control} ${props.isValid === false ? classes.invalid : ''
}`}>
<label htmlFor={props.id}>{props.label}</label>
<input
type="email"
id={props.id}
value={props.value}
onChange={props.onChange}
onBlur={props.onBlur}
/>
</div>
}
export default Input;
Login.js
이렇게 보다시피 Input과 같은 버튼을 재사용할 때는 react context가 아닌 props를 사용해야 한다.
import React, { useState, useEffect, useReducer, useContext } from 'react';
import Card from '../UI/Card/Card';
import classes from './Login.module.css';
import Button from '../UI/Button/Button';
import AuthContext from '../store/auth-context';
import Input from '../UI/Input';
const Login = () => {
const authCtx = useContext(AuthContext);
// const [enteredEmail, setEnteredEmail] = useState('');
// const [emailIsValid, setEmailIsValid] = useState();
// const [enteredPassword, setEnteredPassword] = useState('');
// const [passwordIsValid, setPasswordIsValid] = useState();
const [formIsValid, setFormIsValid] = useState(false);
const emailReducer = (state, action) => {
if (action.type === 'USER_INPUT') {
return { value: action.val, isValid: action.val.includes('@') }
} else if (action.type === 'USER_BLUR') {
return { value: state.value, isValid: state.value.includes('@') }
}
return { value: '', isValid: false };
}
const passwordReducer = (state, action) => {
if (action.type === 'PWD_INPUT') {
return { value: action.val, isValid: action.val.trim().length > 6 };
} else if (action.type === 'PWD_BLUR') {
return { value: state.value, isValid: state.value.trim().length > 6 };
}
return { value: state.value, isValid: 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');
};
}, []);
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) => {
// setEnteredEmail(event.target.value);
dispatchEmail({ type: 'USER_INPUT', val: event.target.value })
setFormIsValid(
emailState.isValid && passwordState.isValid
);
};
const passwordChangeHandler = (event) => {
dispatchPassword({ type: 'PWD_INPUT', val: event.target.value })
// setEnteredPassword(event.target.value);
setFormIsValid(
emailState.isValid && event.target.value.trim().length > 6
);
};
const validateEmailHandler = () => {
// setEmailIsValid(emailState.isValid);
dispatchEmail({ type: 'USER_BLUR' });
};
const validatePasswordHandler = () => {
// setPasswordIsValid(enteredPassword.trim().length > 6);
dispatchPassword({ type: 'PWD_BLUR' });
};
const submitHandler = (event) => {
event.preventDefault();
authCtx.onLogin(emailState.value, passwordState.value);
};
return (
<Card className={classes.login}>
<form onSubmit={submitHandler}>
<Input id="email" label="E-Mail" type="email" isValid={emailIsValid} value={emailState.value} onChange={emailChangeHandler} onBlur={validateEmailHandler} />
<Input id="password" label="Password" isValid={passwordIsValid} value={passwordState.value} onChange={passwordChangeHandler} onBlur={validatePasswordHandler} />
<div className={classes.actions}>
<Button type="submit" className={classes.btn} disabled={!formIsValid}>
Login
</Button>
</div>
</form>
</Card>
);
};
export default Login;
반응형
'온라인 강의 > React 완벽 가이드 [Udemy]' 카테고리의 다른 글
139. 모듈 리소스 (0) | 2023.06.14 |
---|---|
138. Forward Refs"에 대해 알아보기 (1) | 2023.06.14 |
136. "Hooks의 규칙" 배우기 (0) | 2023.06.14 |
135. 리액트 컨텍스트 제한 (0) | 2023.06.14 |
134. 사용자 정의 컨텍스트 제공자 구성요소 빌드 및 사용 (0) | 2023.06.14 |