해석하며 공부하는 것을 목적으로 하기 때문에 다수의 의역, 오역이 있음을 미리 밝힙니다.
원본 : https://reactjs.org/docs/react-api.html
*cloneElement()에 대한 부분이 특히 매끄럽지 않습니다. 주의해서 읽어주세요
React
는 리액트 라이브러리의 시작점입니다. <script>
태그에서 리액트를 불러온다면, 최상위 레벨 API들은 React
전역에서 사용할 수 있습니다. npm을 통해 ES6을 사용하고 있다면, import React from 'react'
를 작성하면 됩니다. npm을 통해 ES5를 사용하고 있다면, var React=require('react')
를 작성하면 됩니다.
리액트 컴포넌트는 UI를 독립적으로, 재사용이 가능하게 분할하도록 하고, 각 부분을 분리하여 생각할 수 있게 도와줍니다. 리액트 컴포넌트는 React.Component
나 React.PureComponent
로 하위 분류됩니다.
ES6을 사용하고 있지 않다면,create-react-class
모듈을 사용하십시오. ES6 없이 리액트 사용하기 문서에서 더 많은 정보를 얻을 수 있습니다.
리액트 컴포넌트는 래핑될 수 있는 함수에 의해서 정의되는 것도 가능합니다.
UI를 묘사하는 데는 JSX를 사용하는 것이 권장됩니다. 각 JSX 엘리먼트는 React.createElement()
를 호출하기 위한 문법적 설탕에 불과합니다. JSX를 사용하고 있다면 아래의 메소드를 직접 호출할 일은 보통 없을 것입니다.
JSX없이 리액트 사용하기 문서에서 더 많은 정보를 얻을 수 있습니다.
React
는 엘리먼트 조작을 위한 여러가지 API를 제공합니다.
React
는 또한 wrapper없이 여러 엘리먼트들을 렌더링하기 위한 컴포넌트를 제공합니다.
Suspense는 렌더링하기 전에 컴포넌트가 무언가를 "기다리는" 것을 가능하게 합니다. 현재 Suspense에는 오직 하나의 사용 예시가 있습니다 : React.lazy를 이용하여 동적으로 컴포넌트 로딩하기 추후에 Suspense는 데이터 불러오기와 다른 사용 예시들도 지원될 것입니다.
Hooks는 리액트 16.8 버전에 새롭게 추가되었습니다. class를 사용하지 않고도 state나 다른 리액트 도구들을 사용할 수 있습니다. Hooks만을 다루는 문서와 API 문서가 존재합니다 :
React.Component
는 ES6 클래스를 사용할 때 리액트 컴포넌트에 가장 기본이 되는 클래스입니다 :
class Greeting extends React.Component{
render(){
return <h1>Hello, {this.props.name}</h1>
}
}
React.Component API Reference에서 기본 React.Component 클래스 관련된 메소드와 프로퍼티 리스트를 확인하실 수 있습니다.
React.PureComponent
는 React.Component
와 아주 비슷합니다. React.Component
는 ShoulComponentUpdate()
를 구현하지 않았고, React.PureComponent
는 prop와 state를 얕은 비교를 통해 비교하는 ShoulComponentUpdate()
를 구현했다는 점에서 차이가 있습니다.
리액트 컴포넌트의 render()
함수가 동일한 props와 state에 대해 동일한 결과를 받는다면, 성능 향상을 위해 React.PureComponent
를 사용하는 것이 좋습니다.
참고
React.PureComponent의 shouldComponentUpdate()는 객체를 얕게만 비교합니다. 이 컴포넌트가 복잡한 데이터 구조를 가졌다면, 깊은 차이를 가짐에도 불구하고 차이가 없다고 판단할 수 있습니다. props와 state의 구조가 간단하다고 예상될 때만 PureComponent를 사용하거나 깊은 데이터 구조가 변화되는 것을 알 때 forceUpdate()를 사용하세요. 또는, 중첩된 데이터의 빠른 비교를 가능하게 하기 위해서 불변의 객체를 사용하는 것을 고려해보는 것도 좋습니다.
더 나아가, React.PureComponent의 shouldComponentUpdate()는 전체 컴포넌트의 하위트리의 prop 업데이트를 건너뜁니다. 모든 자식 컴포넌트가 "pure"인지 확인해주세요.
const MyComponent = React.memo(function
MyComponent(props){
/*prop을 사용해서 렌더링*/
});
React.memo
는 고차 컴포넌트(higher order component)입니다.
컴포넌트다 같은 props에 의해서 같은 결과를 렌더링한다면, 결과를 기억함으로서 높은 성능을 기대하는 Recat.memo
호출로 컴포넌트를 감쌀 수 있습니다. 이것은 리액트는 컴포넌트 렌더링을 건너뛸 수 있고, 마지막으로 렌더링된 결과를 재사용할 수 있다는 뜻입니다.
React.memo
는 prop 변화만 체크합니다. React.memo
로 감싼 함수 컴포넌트가 useState
,useReducer
, 또는 useContext
훅을 사용하여 구현되었다면, 다른 컴포넌트와 마찬가지로 state나 context가 변화할 때 다시 렌더링될 것입니다.
기본적으로 prop 객체 안의 복잡한 객체들은 오로지 얕은 비교만 합니다. 비교 방법을 제어하고 싶다면, 두번째 매개변수에 커스텀 비교 함수를 넣으면 됩니다.
function MyComponent(props){
/*props을 이용하여 렌더링*/
}
function areEqual(prevProps, nextProps){
/* 렌더링할 nextProps를 전달한 것과 prevProps를 전달한
결과가 같다면 true를 반환하고, 아니면 false를 반환한다*/
}
export default React.memo(MyComponent, areEqual);
이 메소드(areEqual)는 성능 최적화를 위해서만 존재합니다. 렌더링을 "방지하기" 위하여 사용하지 마세요. 버그를 유발할 수 있습니다.
참고
shouldComponentUpdate()
메소드가 클래스 컴포넌트에 쓰이는 것과 다르게,areEqaul
함수는 props이 동일하면 true를 반환하고, 동일하지 않으면 false를 반환합니다. 이것은shoulComponentUpdate
와 정반대입니다.
React.createElement(
type,
[props],
[...children]
)
인자로 주어지는 타입에 따라 새로운 리액트 엘리먼트를 만들고 반환합니다. type 매개변수는 태그 이름 문자열('div'나 'span'과 같은)이거나 리액트 컴포넌트 형식(class나 function)이거나 리액트 fragment 형식입니다.
JSX로 작성된 코드는 React.createElement()
로 변환됩니다. JSX를 사용하면 React.createElement()
를 직접 불러오지 않아도 됩니다. 더 많은 정보는 React without JSX를 확인하세요.
React.cloneElement(
element,
[config],
[...children]
);
element
를 기준으로 새로운 리액트 앨리먼트를 복사하고 반환합니다. config
는 모든 새로운 props, key
, ref
를 포함합니다. 결과적으로 만들어지는 엘리먼트는 기존 엘리먼트의 props와 새로운 props가 얕게 병합된 뒤 주어집니다. 새로운 자식 엘리먼트는 기존 엘리먼트를 대체합니다.key
와 ref
가 config
에 없으면 기존 엘리먼트의 key
와 ref
는 보존됩니다.
React.cloneElement()
는 아래와 거의 동일합니다 :
<element.type {...element.props} {...props}>{children}</element.type>
그러나 React.cloneElement()
는 refs
을 보존하기도 합니다.ref
가 자식 컴포넌트에 있다면, 그것을 자식 컴포넌트보다 상위 컴포넌트들로 가져올 수 없습니다.ref
가 붙어있는 새로운 엘리먼트를 받게 될 것입니다. 새로운 ref
나 key
는 오래된 것들을 대체합니다.
이 API는 앞으로 사라지게 될 React.addons.cloneWithProps()
를 대체하기 위해 소개되었습니다.
React.createFactory(type)
주어진 형식의 리액트 엘리먼트들을 만드는 함수를 반환합니다. React.createElement()
처럼, type 매개변수는 'div'나 'span'과 같은 태그 이름 문자열이 될 수도 있고, 클래스나 함수와 같은 리액트 컴포넌트 타입이 될 수도 있고, 리액트 fragment 타입이 될 수도 있습니다.
이 헬퍼 함수는 레거시로 간주되며, JSX나 React.createElement()
를 직접 사용하는 것을 권장합니다.
JSX를 사용한다면 대부분 React.createElement()
를 불러오지 않습니다. 더 많은 정보는 React without JSX를 확인하세요.
React.isValidElement(object)
object가 리액트 엘리먼트인지 확인합니다. true
또는 false
를 반환합니다.
React.Children
은 this.props.children
이라는 불투명 자료구조를 다룰 수 있는 유틸리티들을 제공합니다.
React.Children.map(children, function[(thisArg)])
children
내부의 포함된 모든 자식들에 대해 this
로 thisArg
를 세팅한 함수를 불러옵니다. children
이 배열이라면 배열을 순회하면서 배열의 각 원소에 의해 함수가 호출될 것입니다. 배열의 원소들이 null이나 undefined라면, 이 메소드는 배열보다는 null이나 undefined를 반환할 것입니다.
참고
만약children
이Fragment
라면, 단일 원소로 취급되어서 순회하지 않을 것입니다.
React.Children.forEach(children, function[(thisArg)])
React.Children.map()
과 비슷하지만 배열을 반환하지는 않습니다.
React.Children.count(children)
children
안의 컴포넌트의 총 개수를 반환합니다. 이것은 map
이나 forEach
로부터 전달된 콜백함수가 불려지는 횟수와 같습니다.
React.Children.only(children)
children
이 하나의 자식(리액트 앨리먼트)만을 가지고 있음을 확인하고, 그것을 반환합니다. 그렇지 않으면 오류를 발생시킵니다.
참고:
React.Children.only()
는React.Children.map()
의 반환 값을 받아들이지 않습니다. 반환값이 리액트 앨리먼트가 아니고 배열이기 때문입니다.
React.Children.toArray(children)
불투명 자료 구조인 children
을 각 자식에 할당된 키의 배열로서 반환합니다. render 메소드에서 자식들의 집합을 조작하는데 유용하며, 특히 this.props.children
을 하위 컴포넌트에 전달하기 전에 다시 정렬하거나 일부만 잘라내고 싶을 때 유용합니다.
참고:
React.Children.toArray()
는 중첩된 배열의 의미를 보존하기 위해서 키를 바꿉니다. 즉, 각 엘리먼트의 키는 해당 키가 포함된 입력 배열로 범위가 지정되게 하기 위하여toArray
는 반환된 배열에서의 각 키를 앞에 붙입니다.
React.Fragment
컴포넌트는 render()
메소드에서 추가적인 DOM 엘리먼트를 만들지 않고 여러 개의 엘리먼트들을 반환할 수 있도록 합니다.
render(){
return(
<React.Fragment>
Some.text.
<h2>A heading</h2>
</React.Fragment>
);
}
<React.Fragment>
대신에 <></>
문법을 사용할 수도 있습니다. 더 많은 정보는 React v16.2.0: Fragment을 위한 개선된 설명서를 참조하세요.
React.createRef
는 ref 속성을 통해서 리액트 엘리먼트에 추가될 수 있는 ref
를 만듭니다.
class MyComponent extends React.Component{
constructor(props){
super(props);
this.inputRef=React.createRef();
}
render(){
return <input type="text" ref={this.inputRef} />
}
componentDidMount(){
this.inputRef.current.focus();
}
}
React.forwardRef
는 전달받은 ref 속성을 하부 트리 내의 다른 컴포넌트로 전달하는 리액트 컴포넌트를 만듭니다. 이 기술은 일반적이지 않지만 두 가지 시나리오 상에서는 특히 유용합니다 :
React.forwardRef
매개변수로 렌더링 함수를 받아들입니다. 리액트는 props와 ref를 모두 매개변수로 받아들이는 함수를 호출합니다. 이 함수는 리액트 노드를 반환합니다.
const FancyButton = React.forwardRef((props,ref)=>(
<button ref={ref} className="FacnyButton">
{props.children}
</button>
));
//DOM으로부터 직접 ref를 받는다
const ref=React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>
위의 예시에서 리액트는 <FancyButton ref={ref}>
엘리먼트에 주어진 ref
를 React.forward
호출 시 렌더링 함수의 두번째 인자로 전달합니다. 이러한 렌더링 함수는 ref
를 <button ref={ref}>
엘리먼트로 전달합니다.
결과적으로, 리액트가 ref를 사용함으로서 ref.current
는 <button>
DOM 엘리먼트 인스턴스를 직접 가리키게 됩니다.
더 많은 정보는 ref 전달하기 문서에서 확인하세요.
React.lazy()
는 동적으로 불러오는 컴포넌트를 정의할 수 있습니다. 이것은 초기 렌더링에 사용되지 않는 컴포넌트를 불러오는 것이 지연되도록 하는 번들의 크기를 줄일 수 있습니다.
Code Splitting문서에서 React.lazy()
를 어떻게 사용하는지 배울 수 있으며, 더 자세히 쓸 수 있는 방법에 대해서는 이 문서를 참고해보세요.
//이 컴포넌트는 동적으로 불러옵니다.
const SomeComponent=React.lazy(()=> import('./SomeComponent'));
lazy
컴포넌트를 렌더링하려면 렌더링 트리의 상위에 <React.Suspense>
컴포넌트가 요구됩니다. 로딩 지시자를 불러오는 방법입니다.
참고
동적 import를 통해 React.lazy를 사용하는 것은 JS 환경이 Propmise를 지원해야합니다. IE11 이하에서는 polyfill이 필요합니다.
React.Suspense
는 트리 상에 렌더링이 준비되지 않은 컴포넌트가 있을 때 로딩 지시기를 명시할 수 있게 도와줍니다. 오늘날, lazy 로딩 컴포넌트가 <React.Suspense>
에 의해 지원되는 유일한 사용 예시입니다:
//이 컴포넌트는 동적으로 불러옵니다.
const OtherComponent=React.lazy(()=>import('./OtherComponent'));
import('./OtherComponent');
function MyComponent(){
return(
//OtherComponent가 로딩될 때까지 <Spinner>를 보여줍니다.
<React.Suspense fallback={<Spinner/>}>
<div>
<OtherComponent/>
</div>
</React.Suspense>
);
}
이것은 code splitting 지원 가이드입니다. lazy
컴포넌트는 Suspense
트리의 깊숙히 위치할 수 있다는 것을 주의하세요. 즉, Suspense
가 모든 것을 감쌀 필요는 없다는 것입니다. 가장 좋은 방법은 로딩 지시자를 보고 싶은 곳에 <Suspense>
를 위치시키는 것이지만, Code Splitting을 하고 싶은 어느 곳이든 lazy()를 위치시킬 수 있습니다.
현재는 지원하고 있지 않지만, 추후에 데이터 불러오기와 같은 많은 경우를 다루는 Suspense
를 지원할 예정입니다. 이것에 대한 정보는 로드맵 문서를 참조하세요.
참고:
React.lazy()
와<React.Suspense>
는 아직ReactDOMServer
에 의해 지원되지 않습니다. 이러한 제한 사항은 추후 해결될 예정입니다.