React Native

useRef로 컴포넌트 래퍼런스 선택하기

Beekei 2022. 2. 15. 23:44
반응형

useRef란?

useRef는 함수 컴포넌트에서 컴포넌트의 래퍼런스를 선택할 수 있게 하는 Hook다.

간단히 선택자라고 생각하면 될 것 같다.

 

TextInput 포커스 하기

아래는 제목을 입력하고 Enter를 누르면 하단 내용으로 포커스를 이동시키는 예제 코드다.

import React, {useRef} from "react";
import { View, StyleSheet, TextInput } from "react-native";

function WriteEditor({title, body, onChangeTitle, onChangeBody}) {
  const bodyRef = useRef();
  return (
    <View style={styles.block}>
      <TextInput
        placeholder="제목을 입력하세요"
        style={styles.titleInput}
        returnKeyType="next"
        onChangeText={onChangeTitle}
        value={title} 
        onSubmitEditing={() => {
          bodyRef.current.focus()
        }}/>
      <TextInput
        placeholder="당신의 오늘을 기록해보세요"
        style={styles.bodyInput}
        multiline
        textAlignVertical="top"
        onChangeText={onChangeBody}
        value={body} 
        ref={bodyRef}/>
    </View>
  )
}

...

이렇게 ref를 생성해 TextInput의 Props로 지정해주면 원하는 컴포넌트의 래퍼런스를 선택할 수 있다.

TextInput의 래퍼런스에는 다음과 같은 메서드가 구현되어 있다.

  • .focus() : TextInput에 포커스를 잡아준다.
  • .blur() : TextInput에 포커스를 해제한다.
  • .clear() : TextInput의 내용을 모두 비운다.

제목을 입력하고 다음 버튼 클릭 시 내용으로 포커스

위 예제 코드는 .focus()를 사용했으므로 다음 버튼을 누르면 내용 TextInput으로 포커스가 이동하는 것을 확인할 수 있다.

 

특정 컴포넌트에 포커스 하기

바로 TextInput에 useRef를 사용하는 것이 아닌 특정 컴포넌트 안에 TextInput에 useRef를 적용해야 하는 경우도 있을 것이다. 이럴때는 forwardRef라는 함수를 사용해야 한다.

 

상위 컴포넌트에서 Props로 ref를 받아 TextInput에 적용하고,

제일 하단에 React.forwardRef 함수를 사용해 해당 컴포넌트를 인수로 넣어주고 export 해준다.

import React from "react";
import { StyleSheet, TextInput } from "react-native";

function CustomTextInput({...rest}, ref) { 
    return (
        <TextInput {...rest} ref={ref} />
    )
}

export default React.forwardRef(CustomTextInput);

아래처럼 사용하면 이메일 input에서 입력 후 키보드에 next 버튼을 클릭하게 되면 비밀번호 input으로 포커스가 될 것이다.

import React, { useRef } from "react";
import CustomTextInput from "../components/CustomTextInput";


function Write() {
    const passwordRef = useRef();
    
    return (
    	<CustomTextInput 
            placeholder="이메일" 
            returnKeyType="next"
            onSubmitEditing={() => passwordRef.current.focus()} 
            />
        <CustomTextInput 
            placeholder="비밀번호" 
            returnKeyType="done"
            ref={passwordRef} 
            />
    );
}

export default Write;
반응형