React/basic
10. (3) hooks / useState
aloha2jh
2020. 7. 26. 15:04
import React ,{ useState } from 'react';
const ResponseCheck = () => {
const [ color, setColor ] = useState('waiting');
const [ message, setMessage ] = useState('클릭해서 시작');
const [ result, setResult] = useState([]);
// timeout;
// startTime; //시작시간
// endTime; //클릭한시간
const onClickScreen = ()=>{
if( color === 'waiting'){// waiting일때 클릭을 한 경우
setColor('ready');
setMessage('초록색이되면 클릭하시면 됩니다');
timeout = setTimeout(()=>{
this.setState({
color:'now',
message:'클릭하세요',
});
startTime = new Date(); //////
} , Math.floor( Math.random()*1000 )+2000 )
}else if( color === 'ready'){ // ready일때 클릭한 경우
clearTimeout(this.timeout);
setColor('waiting');
setMessage('성급했다. 초록색된후에 클릭할것');
}else if( color === 'now'){ // 클릭하라할때 클릭한 경우
endTime = new Date(); ///////
setColor('waiting');
setMessage('클릭해서 시작하세요');
setResult( (prevResult )=>{ return [ ...prevResult, endTime-startTime]} );
}
}
const onReset = () => {
setResult([]);
}
const getAverage = () => {
return result.length === 0 ? null :
<><p>평균시간: {result.reduce((a,c)=>a+c) / result.length} ms </p>
<button onClick={ this.onReset }>리셋</button></>
}
return (
<>
<div id="screen" className={color} onClick={onClickScreen} >
{message}
</div>
{ getAverage() }
</>
)
}
export default ResponseCheck;
hook로 바꾸기
useState, method-> const 에 arrayFunction , return
1. useState
(useState가 이해가안되서 좀더 찾아봄)
-react패키지의useState함수를 불러와서, 상태의 기본값을 인자로 넣어서 호출해주는것.인데
const [ color, setColor ] = useState('waiting');
위의 코드와 아래 코드는 같다
const colorState = useState('waiting');
const color = colorState[0];
const setColor = colorState[1];
useState('초기값') 함수를 호출하면 배열을 반환한다.
그 배열은 2개 아이템이 있다.
첫번째 배열[0] 은 상태값,
두 번째 아이템[1]은 상태값을 갱신해주는 함수.(이 함수호출시 리렌더링 된다)
그래서 배열 구조분해를 통해
const [ color, setColor ] = useState('waiting');
이런방식으로 써서, color가 현재 상태값, setColor로 상태값 업데이트로 사용.
(배열구조분해 예시)
const array = ['dog', 'cat', 'sheep'];
const [first, second] = array;
console.log(first, second); // dog cat
2. 메서드함수를 변수에담아주고
3. return
class component 의 filed (property) 값을 ref로 바꾼다.
(dom에 접근할때만 ref를 썻었지만) hooks에서는 this의 속성들을 ref로 표현한다.
// class component
timeout;
startTime;
endTime;
// hooks
const timeout = useRef(null);
const startTime = useRef();
const endTime = useRef();
-ref는 안에 current가 들어있기 때문에
값을 넣어줄때 , 가져올때 target.current
//class
this.startTime = new Date();
// hooks
starttime.current = new Date();
state vs ref ?
setState할때 return부분이 다시실행되지만,
useRef의 값들을 바꿀때는 return부분이 다시실행되지 않음
불필요한렌더링을 막기 위해, 값이바껴도 렌더링 시키고 싶지 않을경우(화면에는 영향을 미치고 싶지 않을때)
ref에 넣어서 쓰면 된다
import React ,{ useState , useRef } from 'react';
const ResponseCheck = () => {
const [ color, setColor ] = useState('waiting');
const [ message, setMessage ] = useState('클릭해서 시작');
const [ result, setResult] = useState([]);
const timeout = useRef(null);
const startTime = useRef();
const endTime = useRef();
const onClickScreen = ()=>{
if( color === 'waiting'){// waiting일때 클릭을 한 경우
setColor('ready');
setMessage('초록색이되면 클릭하시면 됩니다');
timeout.current = setTimeout(()=>{
setColor('now');
setMessage('click !!!');
startTime.current = new Date(); //////
} , Math.floor( Math.random()*1000 )+2000 )
}else if( color === 'ready'){ // ready일때 클릭한 경우
clearTimeout( timeout.current );
setColor('waiting');
setMessage('성급했다. 초록색된후에 클릭할것');
}else if( color === 'now'){ // 클릭하라할때 클릭한 경우
endTime.current = new Date(); ///////
setColor('waiting');
setMessage('클릭해서 시작하세요');
setResult( (prevResult )=>{ return [ ...prevResult, endTime.current -startTime.current]} );
}
}
const onReset = () => {
setResult([]);
}
const getAverage = () => {
return result.length === 0 ? null :
<><p>평균시간: {result.reduce((a,c)=>a+c) / result.length} ms </p>
<button onClick={ onReset }>리셋</button></>
}
return (
<>
<div id="screen" className={color} onClick={onClickScreen} >
{message}
</div>
{ getAverage() }
</>
)
}
export default ResponseCheck;