React.js Refs, Context API
30 Jan 2021 | ReactReact.js Refs, Context API
-
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> ) }
-
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> ) }