코드 분리
코드를 분리해 4월46일에 만든 로그인기능을 유지해보았다.
다른 컴포넌트처럼 import로 가져올 수 있고, export default로 내보낼 수 있다.
// 내보낼때
export default useForm
// 가져올때
import useForm from './useForm.jsx'
비동기 코드 넘기기
중간에 상태값이 바뀌어서 재실행될때 코드는 비동기적으로 움직인다.
올바르게 회원가입을 했을때 1초후에 가입한 정보를 띄우는 비동기적 코드를 작성해보았다.
// 강제적으로 비동기 코드를 작성
// submit을 클릭했을때 items를 최신상태로 바꾸기
const request = async (items) => {
const result = await new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(items)
},1000)
})
}
// useForm.jsx로 넘겨버리기
const Form = () => {
const {
userid,
password,
errors,
submit,
handleSubmit
} = useForm({userid:'',password:''},aa)
비동기 코드 받기
그러면 내용을 받는 코드에서도 비동기로 가도록 이렇게 async를 붙여야하지만, 에러가 난다.
에러내용 : 콜백함수 안에 함수를 따로 선언해서 해라.
useEffect( async ()=>{} )
문제점 해결한 비동기 코드
useEffect( ()=>{
// 함수생성
const init = async () => {
if(submit){
if(Object.keys(errors).length === 0){
onSubmit(values)
}
setSubmit(false)
}
}
init() // 호출
}, [errors]
)
최종코드
더보기
// Form.jsx
import React,{useState,useEffect} from 'react'
import validate from '../utils/validate.jsx'
import useForm from './useForm.jsx'
// submit을 실행했을때 items의 최신형을 가져올 수 있음
const request = async (items) => {
// 강제적 비동기
const result = await new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(items)
},1000)
})
alert(JSON.stringify(result))
}
const Form = () => {
const {
userid,
password,
errors,
submit,
handleSubmit
} = useForm({userid:'',password:''},request,validate)
/*
password:{value:'', onChange: f}
userid:{value:'', onChange: f}
errors:{},
submit:boolean,
handleSubmit:f()=>{}
*/
return(
<form onSubmit={handleSubmit}>
<ul>
<input type="text" name="userid" {...userid} className={errors.userid && 'error'}/>
{errors.userid && <span>{errors.userid}</span>}
</ul>
<ul>
<input type="text" name="password" {...password}/>
{errors.password && <span>{errors.password}</span>}
</ul>
<ul>
<input type="submit" value="회원가입" disabled={submit}/>
</ul>
</form>
)
}
export default Form
// useForm.jsx
import React,{useState,useEffect} from 'react'
const useForm = (defaultValues,onSubmit,validate) => {
const [values,setValues] = useState(defaultValues)
const [submit,setSubmit] = useState(false)
const [errors,setErrors] = useState({})
const onChange = e => {
const {name,value} = e.target
setValues({...values,[name]:value})
}
const handleSubmit = e => {
e.preventDefault()
setSubmit(true)
//values:{userid:'adsd', password:'afasdf'}
setErrors(validate(values))
}
useEffect( ()=>{
const init = async () => {
if(submit){
if(Object.keys(errors).length === 0){
onSubmit(values)
}
setSubmit(false)
}
}
init()
}, [errors]
)
return{
...Object.keys(defaultValues).reduce((acc,v)=>{
acc[v] = {
value:values[v],
onChange
}
return acc
},{}),
handleSubmit,
errors,
submit
}
}
export default useForm;
'프로그래밍 > react' 카테고리의 다른 글
[220428] useReducer (0) | 2022.05.06 |
---|---|
[220428] React.memo / useMemo / useCallback / Context (0) | 2022.05.05 |
[220426] 회원가입창 만들기 / useEffect (0) | 2022.05.03 |
[220426] 회원가입창 만들기 / useState (0) | 2022.05.03 |
[220425] 함수컴포넌트로 로그인기능 생성, props 값 넘기기 (0) | 2022.05.02 |
댓글