반응형
이 강의는 못 알아듣겠다!
이해가 안돼서 생활 코딩의 힘을 빌리기
useState의 경우는 고객이 직접 장부에 기록하는 법을 알아서 실행하는 것이다
useReducer의 경우는 고객이 직접 작성하지 않고 주문을 한다
첫번째 인자는 회계직원 즉 함수, 두번째 인자는 초기값
일반적으로 useState를 사용할 때
import React from 'react';
import './style.css';
import { useState, useReducer } from 'react';
export default function App() {
const [val, setVal] = useState(0);
const valDown = () => {
setVal(val - 1);
};
const valUp = () => {
setVal(val + 1);
};
const valReset = () => {
setVal(0);
}
return (
<div>
<button onClick={valDown}><</button>
<button onClick={valReset}>{val}</button>
<button onClick={valUp}>></button>
</div>
);
}
useReducer를 사용할 때
import React from 'react';
import './style.css';
import { useReducer } from 'react';
export default function App() {
const countReducer = (oldCount, action) => {
if(action === 'down') {
return oldCount - 1;
} else if(action === 'up') {
return oldCount + 1;
} else if(action === 'reset') {
return 0;
}
}
const [count, countDispatch] = useReducer(countReducer, 0);
const valDown = () => {
countDispatch('down');
};
const valUp = () => {
countDispatch('up');
};
const valReset = () => {
countDispatch('reset');
}
return (
<div>
<button onClick={valDown}><</button>
<button onClick={valReset}>{count}</button>
<button onClick={valUp}>></button>
</div>
);
}
useReducer 해당 강의 복습 중
Email Reducer
Email Valid 와 set을 함께 묶어서 useRedcuer를 사용해보자
1. useReducer 사용
const [emailState, dispatchEmail] = useReducer();
useReducer() 를 이용해서 state와 dispatch를 생성
useReducer 내부에는 함수와 인자가 들어간다.
const emailReducer = () => {
return {value: '', isValid: false};
}
const [emailState, dispatchEmail] = useReducer(emailReducer, {value: '', isValid: false});
state는 최신의 스냅샷이다
이해가 가기 시작했다.
즉 useReducer란?
const [] = useReducer();
// useReducer 선언
const [emailState, dispatchEmail] = useReducer();
// dispatchEmail은
const [emailState, dispatchEmail] = useReducer(()=>{}, {value: '', isValid: false});
// useReducer는 함수와 객체(인자)를 받는다
const [emailState, dispatchEmail] = useReducer(emailReducer, {value: '', isValid: false});
// 그리고 기존의 setEmail() 함수를 변경한다
dispatchEmail();
dispatchEmail({type: 'USER_INPUT', val: event.target.value});
// 해당 매개변수는 emailReducer 함수에서 처리된다.
const emailReducer = (state, action) => {
if(action.type === 'USER_INPUT') {
return { value: action.val, isValid: action.val.includes('@') }
// 이 return 값은 어디로 가는 걸까?
// useReducer의 두번째 인자 {}
}
}
action과 state의 차이를 더 알아봐야 할 것 같다
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';
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 emailReducer = (state, action) => {
console.log('emailReducer 실행중');
if (action.type === 'USER_INPUT') {
console.log('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 [emailState, dispatchEmail] = useReducer(emailReducer, { value: '', isValid: null });
useEffect(() => {
console.log('EFFECT RUNNING');
return () => {
console.log('EFFECT CLEANUP');
};
}, []);
// useEffect(() => {
// const identifier = setTimeout(() => {
// console.log('Checking form validity!');
// setFormIsValid(
// enteredEmail.includes('@') && enteredPassword.trim().length > 6
// );
// }, 500);
// return () => {
// console.log('CLEANUP');
// clearTimeout(identifier);
// };
// }, [enteredEmail, enteredPassword]);
const emailChangeHandler = (event) => {
console.log("hello");
// setEnteredEmail(event.target.value);
dispatchEmail({ type: 'USER_INPUT', val: event.target.value })
setFormIsValid(
emailState.isValid && enteredPassword.trim().length > 6
);
};
const passwordChangeHandler = (event) => {
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);
};
const submitHandler = (event) => {
event.preventDefault();
props.onLogin(enteredEmail, enteredPassword);
};
return (
<Card className={classes.login}>
<form onSubmit={submitHandler}>
<div
className={`${classes.control} ${emailIsValid === 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} ${passwordIsValid === false ? classes.invalid : ''
}`}
>
<label htmlFor="password">Password</label>
<input
type="password"
id="password"
value={enteredPassword}
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;
password까지 완료
setIsForm 때문에 한창 헤맷지만 성공
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';
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 emailReducer = (state, action) => {
console.log('emailReducer 실행중');
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') {
console.log(action.val.trim().length > 6);
return { value: action.val, isValid: action.val.trim().length > 6 };
} else if (action.type === 'PWD_BLUR') {
console.log(state.value.trim().length > 6);
return { value: state.value, isValid: state.value.trim().length > 6 };
}
console.log(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');
};
}, []);
// useEffect(() => {
// const identifier = setTimeout(() => {
// console.log('Checking form validity!');
// setFormIsValid(
// enteredEmail.includes('@') && enteredPassword.trim().length > 6
// );
// }, 500);
// return () => {
// console.log('CLEANUP');
// clearTimeout(identifier);
// };
// }, [enteredEmail, enteredPassword]);
const emailChangeHandler = (event) => {
console.log("hello");
// setEnteredEmail(event.target.value);
dispatchEmail({ type: 'USER_INPUT', val: event.target.value })
setFormIsValid(
emailState.isValid && passwordState.value.trim().length > 6
);
};
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();
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;
반응형
'온라인 강의 > React 완벽 가이드 [Udemy]' 카테고리의 다른 글
128. 중첩 속성을 useEffect에 종속성으로 추가하기 (0) | 2023.06.14 |
---|---|
127. useReducer & useEffect (0) | 2023.06.14 |
125. useReducer 및 Reducers 일반 소개 (0) | 2023.06.11 |
124. useEffect 요약 (0) | 2023.06.10 |
123. useEffect에서 Cleanup 함수 사용하기 (0) | 2023.06.10 |