Archive

React.js Refs, Context API

|

React.js Refs, Context API


  1. ref

    • ref는 render 메소드에서 생성된 DOM 노드나 리액트 element에 접근하는 방법을 제공한다
    • 일반적으로 상위&하위 컴포넌트간 상호작용은 props를 이용하지만 ref를 이용해서 하위 컴포넌트를 직접 수정할 수 있다
    • focus, 텍스트 선택영역, 미디어 재생, 애니메이션 실행, third party library를 사용할 때 등이 있다
    • 16.3 이후 React.createRef() 메소드로 ref를 생성한다
    • 일반적으로 클래스 컴포넌트에서만 작동을 하고 hook을 이용해 useRef() 메소드를 함수 컴포넌트 안에서 사용하는 것은 가능하다
    • React는 ref 남용을 지양하고 있다
    // 클래스 컴포넌트 안에서...
       
    componentDidMount() {
        this.inputElement.focus();
    }// 컴포넌트가 마운트되면 input에 focus
       
    render() {
        return(
        	<input 
                ref={(inputEl) => {this.inputElement = inputEl}}
            ></input>
        )
    }// 익명 Arrow func으로 참조 연결
    
    // React 16.3 이후
       
    class xxx extends Component {
        constructor(props) {
            super(props);
            this.inputRef = React.createRef(); // 내장 메소드를 이용
        }
        componentDidMount() {
            this.inputRef.current.focus();
        }// 주의: ref를 current 프로퍼티의 값으로 받기에 명시적으로 적어야한다 
        render() {
            return(
            	<input ref={this.inputRef}></input>
            )
        }
    }
    
    // function 컴포넌트 안에서...
    import React, { useRef,useEffect } from 'react'; // import 주의
       
    const xxx = (props) => {
        const inputRef = useRef(null); // 초기값은 null이다
           
        useEffect(() => {
            inputRef.current.focus();
        }, []);
        // ref를 바로 사용하는 것은 좋지 않다. nullPointerException
        // 참조연결이 된 첫 번째 렌더링이 끝나고 사용하는 것이 바람직
        return(
            <input ref={inputRef}></input>
        )
    }
    


  2. Context API

    • App이 방대해질수록 상위 컴포넌트와 그 아래 하위컴포넌트의 개수가 늘어나기마련.
    • 이때, 최상위 컴포넌트에서 최하위 컴포넌트에 props를 전달하기 위해서는 연결된 chain layer들을 다 거치고 나서 전달해야한다
    • 이런 비효율적인 방식을 해결해주는 것이 Context API이다
    // Context를 저장할 js파일을 생성한다
    import React from 'react';
       
    const authContext = React.createContext({
        isLogin: false;
        login: () => {}
    });
       
    export default context;
    
    // Context Provider (데이터를 넘겨줄 최상위 컴포넌트)
    import AuthContext from '../context/context'; // context 별도의 폴더에 관리
       
    class App extends Component {
        constructor(props){
            super(props);
            this.state = {
                isLogin: false; // 전달할 state
            }
        }
        loginHandler = () => {} // 전달할 메소드
          
        render() {
            return (
            	<AuthContext.Provider //사용처를 감싸주고 value 전달
                    value=>
                	<Person />
                </ AuthContext.Provider>
            )
        }
    }
    
    // Context Consumer (데이터를 받을 최하위 혹은 하위 컴포넌트)
    import AuthContext from '../context/context';
       
    class Person extends Component {
        render() {
            return(
            	<AuthContext.Consumer> // 사용처를 감싸고 context 사용
                	{context => context.isLogin ? 
                    	<p>hi</p>
                    	: <p>please log in</p>}
                </ AuthContext.Consumer>
               
            )
        }
    }
    


    • React 16.6 이후 새로운 방식으로 context를 이용할 수 있다 (클래스 컴포넌트)
    import AuthContext from '../context/context';
       
    // 주의 반드시 static 지시어와 지정된 name을 사용해야함
    static contextType = AuthContext;
       
    render() {
        return( // 자동으로 변환하기 때문에 context 지정어를 사용해야함
        	{this.context.isLogin ? 
            	<p>hi</p>
            	: <p>please log in</p>}
        )
    }// 위 코드와 비교
    


    • 하지만, 함수 컴포넌트에서는 static 지시어를 사용할 수 없다
    • hook을 이용해 useContext()로 위와 동일한 효과를 낼 수 있다
    import React, { useContext } from 'react'; // import 주의
    import AuthContext from '../context/context';
       
    const person = props => {
        // useContext() 메소드를 이용해 context 저장
        const authContext = useContext(AuthContext);
           
        return(
        	<button onClick={authContext.login}>Login</button>
        )
    }
    




참고 자료


reactjs.org - 공식홈페이지

Udemy - React The Complete Guide