function FancyButton(props) {
return(
<button className="FancyButton">
{props.children}
</button>
)
}
포커스, 선택, 애니메이션을 관리하기 위해서는 이런 DOM 노드에 접근하는 것이 불가피할 수 있습니다.
Ref 전달하기는 일부 컴포넌트가 수신한 ref를 받아 조금 더 아래로 전달 할 수 있는 옵트인 기능입니다.
const FancyButton = React.forwardRef((props,ref)=>(
<button ref={ref} className="FancyButton"> {props.children} </button>
))
const ref = React.createRef();
<FancyButton ref ={ref}> Click me!</FancyButton>;
다음은 React.forwardRef를 사용하여 전달된 ref를 얻고, 그것을 렌더링 또는 DOM button으로 전달합니다. 이러한 방식으로 FancyButton을 사용하는 컴포넌트들은 button DOM 노드에 대한 참조를 가져올 수 있고, 필요한 경우 DOM button을 직접 사용하는 것처럼 접근할 수 있습니다.
function logProps(WrappedComponent){
class LogProps extends React.Component {
componentDidUpdate(prevProps) {
console.log('old props:', prevProps) ;
console.log('new props:', this.props);
}
render() {
return <WrappedComponent {...this.props} />
}
}
return LogProps;
}
"logProps"는 모든 props를 래핑하는 컴포넌트로 전달하므로 렌더링 된 결과가 동일하게 됩니다. 예를 들어, 이 HOC를 사용해서 "fancy button" 컴포넌트로 전달하는 모든 props를 기록 할 수 있습니다.
class FancyButton extends React.Component {
focus(){
//...
}
//...
}
export default logProps(FancyButton);
위 예시에서는 refs는 전달되지 않는 것 입니다. 그것은 ref는 prop이 아니기 때문입니다. key와 마찬가지로 ref는 React에서 다르게 처리합니다. HOC에 Ref를 추가하면 ref는 래핑 된 컴포넌트가 아니라 가장 바깥쪽 컨테이너 컴포넌트를 참조합니다.
FacnyButton 컴포넌트를 위한 refs가 실제로는 LogProps 컴포넌트에 첨부된다는 것을 의미합니다.
import FacnyButton from "./FancyButton";
const ref = React.createRef();
<FancyButton
label="Click me"
handleClick={handleClick}
ref={ref}
/>
여기서 ref는 내부 FacnyButton 컴포넌트 대신 LogProps를 가르킵니다. 예를 들어 ref.current.focus()를 호출 할 수 없습니다.
React.forwardRef API를 사용하여 내부 FancyButton 컴포넌트에 대한 refs를 명시적으로 전달할 수 있습니다. React.forwardRef는 props와 ref 파라미터를 받아 React 노드를 반환하는 렌더링 함수를 받습니다.
function logProps(Component){
class LogProps extends React.Component{
componentDidUpdate(prevProps){
console.log("old props: ", prevProps);
console.log('new props: ', this.props);
}
}
render(){
const {forwardedRef, ...rest} = this.props;
return <Component ref={forwardedRef} {...rest}/>
}
}
return React.forwardRef((props, ref)=>{
return <LogProps {...props} forwardedRef={ref}/>
})