Dom을 선택하는 useRef
앞에서 Dom을 선택하는 React.createRef()를 살펴보았다.
useRef() 훅은 이것을 대신할 수 있습니다.
CodePen
See the Pen useRef example1 by LeeDongKee (@eastflag) on CodePen.default
AddFormPlayer에 적용
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
import React, {useRef, useState} from 'react'; const AddPlayerForm = (props) => { const [value, setValue] = useState(''); let formRef = useRef(); let textRef = useRef(); const handleValueChange = (e) => { setValue(e.target.value); }; const handleSubmit = (e) => { e.preventDefault(); console.log(formRef.current.checkValidity()); console.log(textRef.current.validity.valid); if (!formRef.current.checkValidity()) { return; } props.addPlayer(value); setValue(''); } return ( <form ref={formRef} className="form" onSubmit={handleSubmit} noValidate> <input ref={textRef} className="input" type="text" placeholder="enter a player's name" value={value} onChange={handleValueChange} required></input> <input className="input" type="submit" value="Add Player"></input> </form> ) } export default AddPlayerForm; |
컴포넌트의 변수를 저장하는 useRef
useRef Hook 은 DOM 을 선택하는 용도 외에도, 다른 용도가 한가지 더 있는데, 바로, 컴포넌트 안에서 조회 및 수정 할 수 있는 변수를 관리하는 것이다.
CodePen
See the Pen useRef example2 by LeeDongKee (@eastflag) on CodePen.default
Stopwatch 수정
isRunning 값을 기억하도록 useRef 훅을 사용해서 저장한다.
이제 로그를 찍어보면 refIsRunning.current 값이 바뀌는것을 할 수 있다.
그러나, 코드는 여전히 동작하지 않는다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
... const refIsRunning = useRef(isRunning); const tick = () => { console.log('tick: ', isRunning, refIsRunning.current); // isRunning이 true이면 timer를 1씩 증가 if (refIsRunning.current) { setTimer(timer + 1) } } const handleStopwatch = () => { refIsRunning.current = !refIsRunning.current; setIsRunning(refIsRunning.current); } ... |
그 이유는 timer 변수도 tick 함수로 값이 전달되고 연결이 되지 않기 때문이다.
setTimer 함수는 setState와 마찬가지로 이전값을 파라메터로 받는 함수를 적용할 수 있다. setTimer를 함수로 아래와 같이 변경한다.
1 2 3 4 5 6 7 8 9 |
... const tick = () => { console.log('tick: ', isRunning, refIsRunning.current); // isRunning이 true이면 timer를 1씩 증가 if (refIsRunning.current) { setTimer(timer => timer + 1) } } ... |