input의 포커스를 주기 위해서는 useRef를 이용해 해당 input창에 포커스를 줄 수 있다.
const TestPage = () => {
const [first, setFirst] = useState("")
const firstRef = useRef(null)
const secondRef = useRef(null)
useEffect(() => {
firstRef.current.focus()
},[]}
const onChangeFirst = (e) => {
setFirst(e.target.value)
if(first.length === 5){
secondRef.current.focus()
}
}
return (
<div>
<input ref={firstRef} onChange={onChangeFirst}/>
<input ref={secondRef}/>
</div>
)
}
위의 코드 처럼 작성하게 되면
처음에 렌더링 됬을 때 첫번째 input에 포커스가 위치하게 되고, 첫번째 input에 글자가 5글자가 되면 두번째 input으로 포커스를 이동시킬 수 있다.
focus를 풀고 싶으면 XXX.current.focus()
대신 XXX.current.blur()
를 주면 포커스를 풀 수 있다.
1번과 같이 같은 컴포넌트에서 ref를 사용하면 상관이 없지만 ref를 props로 넘겨줄 경우가 있다.
예를 들어 input을 다른 공통 컴포넌트에서 불러올 경우가 이런 경우가 해당된다.
이때 forwardRef를 이용하면 쉽게 해결할 수 있다.
//test.js
const TestPage = () => {
const [first, setFirst] = useState("")
const firstRef = useRef(null)
const secondRef = useRef(null)
useEffect(() => {
firstRef.current.focus()
},[]}
const onChangeFirst = (e) => {
setFirst(e.target.value)
if(first.length === 5){
secondRef.current.focus()
}
}
return (
<div>
<MyInput ref={firstRef} onChange={onChangeFirst}/>
<MyInput ref={secondRef}/>
</div>
)
}
위와 같이 작성하면 MyInput에서 에러가 난다.
이유는 import한 컴포넌트에서 ref를 찾을 수 없다고 하기 때문이다.
forwarRef를 이용할 경우
// test.js
const TestPage = () => {
const [first, setFirst] = useState("")
const firstRef = useRef(null)
const secondRef = useRef(null)
useEffect(() => {
firstRef.current.focus()
},[]}
const onChangeFirst = (e) => {
setFirst(e.target.value)
if(first.length === 5){
secondRef.current.focus()
}
}
return (
<div>
<MyInput ref={firstRef} onChange={onChangeFirst}/>
<MyInput ref={secondRef}/>
</div>
)
}
test.js 부분은 동일하게 작성해주고
// MyInput.js
const MyInput = (props, ref) => {
return(
<input ref={ref} onChange={props.onChange}/>
)
}
export default forwardRef(MyInput)
MyInput.js를 작성할때 export default 부분을 forwardRef(컴포넌트이름)으로 감싸주고 이때 props와 함께 ref를 인자로 넘겨주면 된다.
export default에 뒤에 forwardRef를 붙히기 싫다면 다음과 같이 작성해도 된다.
// MyInput.js
const MyInput = forwardRef((props, ref) => {
return(
<input ref={ref} onChange={props.onChange}/>
)
})
export default MyInput
함수 자체를 forwardRef로 감싸서 props와 ref를 넘겨주는 방식이 있다.
개인의 취향대로 사용하면 될 거 같다.