[React-Native] useRef

Joy·2022년 10월 6일

리액트 네이티브

목록 보기
1/2

코드를 보겠습니다.

const refContainer = useRef(initialValue);

useRef 훅은 .current 속성이 initialValue로 초기화된 ref 객체를 반환합니다.

그런데 ref 사용이 익숙하지 않은 분들은 이 말이 조금 어려우실지도 모르겠습니다.

ref

여기서 ref 객체는 render 메서드에서 생성된 DOM 노드 혹은 React 엘리먼트에 접근하는 방법을 제공합니다.

잠시 짚고 넘어가자면, 리액트에서는 ref 객체를 이렇게 사용했습니다.

class MyComponent extends React.Component {
	constructor(props) {
    	super(props);
        this.myRef = React.createRef();
    }
    render() {
    	return <div ref={this.myRef} />
    }
}

리액트 공식 문서에 나와있는 예제를 살펴봤습니다. ref가 render 안에 있는 엘리먼트에 전달될 때, 해당 노드에 대한 참조는 ref의 current 속성으로 접근 가능합니다.

const node = this.myRef.current;

ref는 사실 일반 객체입니다. ref를 console.log로 찍어 보면, current 프로퍼티를 하나 가진 객체라는 것을 알 수 있습니다.


Animated 객체에서 useRef 훅 사용

그렇다면 관련 예제를 통해 useRef를 한층 더 알아보겠습니다. 리액트 네이티브의 Animated 객체를 사용할 때 useRef를 사용합니다.

import React, {useRef} from 'react';
import {Animated, Text, View, StyleSheet, Button, SafeAreaView} from 'react-native';

const App = () => {
	const fadeAnim = useRef(new Animated.Value(0)).current;
    
    const fadeIn = () => {
    	Animated.timing(fadeAnim, {
        	toValue: 1,
            duration: 5000
        }).start();
    };
    
    const fadeOut = () => {
    	Animated.timing(fadeAnim, {
        	toValue: 0,
            duration: 3000
        }).start();
    };
    
    return (
		<SafeAreaView style={styles.container}>
        	<Animated.View
            	style={[
                	styles.fadingContainer,
                    {
                    	opacity: fadeAnim
                    }
                ]}
            >
            	<Text style={styles.fadingText}>Fading View!</Text>
            </Animated.View>
            <View style={styles.buttonRow}>
            	<Button title="Fade In View" onPress={fadeIn} />
                <Button title="Fade Out View" onPress={fadeOut} />
            </View>
        </SafeAreaView>
	);
}

const styles = StyleSheet.create({
	container: {
    	flex: 1,
        alignItems: 'center',
        justifyContent: 'center'
    },
    fadingContainer: {
    	padding: 20,
        backgroundColor: 'powerblue'
    },
    fadingText: {
    	fontSize: 28
    },
    buttonRow: {
    	flexBasis: 100,
        justifyCOntent: 'space-evenly',
        marginVertical: 16
    }
});

export default App;

fadeAnim

  • Animated 객체를 사용하려면 일단 Value를 하나 만들어야 합니다. 이 Value를 만들 때 이렇게 useRef를 사용해야 합니다.
  • 앞에서 설명했듯이, 컴포넌트의 레퍼런스를 선택할 때 useRef를 사용하는데, 레퍼런스 선택 외에 특정 값을 컴포넌트 생성 시에 설정하고, 컴포넌트가 사라질 때까지 재사용하고 싶은 경우에도, useRef를 사용하여 구현할 수 있습니다.
  • Value 생성자 함수의 인자로 초깃값 0을 넣었습니다. 이 값(fadeAnim)을 리액트 컴포넌트의 스타일에 적용했습니다.

Animated.timing

  • 예시 코드에서 컴포넌트의 투명도(opacity) 값을 fadeAnim이 가리키고 있는 값으로 설정했죠. 추후 이 값을 변경해야 할 때, Animated.timing 이라는 함수를 이용했습니다.
  • 여기서 toValue, useNativeDriver 값을 필수로 지정해야 합니다. toValue는 어떤 값으로 변경할지에 대한 값입니다. useNativeDriver는 네이티브 드라이버 사용 여부에 대한 값입니다.

Animated.View

  • Animated 뒤에 사용하고 싶은 리액트 네이티브 컴포넌트의 이름을 넣어주면 됩니다.
    (Animated.View, Animated.Text, Animated.Image ... )

애니메이션은 .start()로 시작하고, 이 함수에 콜백 함수를 인자로 넣어주면, 애니메이션이 끝난 후 호출됩니다.


useRef

리액트 컴포넌트는 기본적으로 내부 상태(state)가 변할 때마다 다시 렌더링 됩니다.

그런데 리렌더링에 독립적인 state를 사용해야 하는 상황이 있을 수 있습니다. 즉, 리렌더링이 되어도 참조하고 있는 값이 동일하게 유지되어야 할 때, 해결 방법으로 useRef 훅을 사용합니다.

공식 문서에 나와 있는 정의로 정리하고 마치겠습니다.

  • 본질적으로, useRef 훅은 마치 .current 프로퍼티라는, 변경 가능한 값을 담고 있는 상자와도 같습니다.

  • 그리고 이 .current 프로퍼티 값이 변경되더라도 이것으로 인해 리렌더링을 발생시키지 않습니다.

profile
Fundamental joy.

0개의 댓글