programing

React에서 forwardRef()를 사용하려면 어떻게 해야 합니까?

javamemo 2023. 4. 5. 21:14
반응형

React에서 forwardRef()를 사용하려면 어떻게 해야 합니까?

현재 리액트 앱에서 다음 오류가 발생하고 있습니다.

함수 구성 요소는 참조를 제공할 수 없습니다.이 참조에 액세스하려고 하면 실패합니다.React.forwardRef()를 사용하시겠습니까?

forwardRef()를 사용하여 이 문제를 해결하려면 어떻게 해야 합니까?

제 코드는 다음과 같습니다.

const Services: FunctionComponent = (): ReactElement => {
  const servicesRef = useRef(null);

  return (
    <Layout>
      <ServicesList ref={servicesRef} />
    </Layout>
  );
};
export default Services;



const ServicesList: React.FunctionComponent = ({ children }: Props) => {
  return (
    <section className="my-24 md:my-32">
      {children && children}
    </section>
  );
};

export default ServicesList;

forwardRefapi, (와 함께 사용)useImperativeHandle후크)를 사용하면 사용자 정의 컴포넌트 내에서 참조를 배치하는 방법과 위치를 사용자 정의할 수 있습니다.또한 커스텀 함수 컴포넌트에 ref를 전달할 수 있는 유일한 방법은 forwardRef입니다.

첫째, ref는 클래스 컴포넌트, 함수 컴포넌트 및 일반 DOM 요소에서 다르게 동작한다는 것을 이해하는 것이 중요합니다.

문서에서:

ref 값은 노드의 유형에 따라 달라집니다.

  1. ref 속성이 HTML 요소에서 사용되는 경우 React.createRef()를 사용하여 컨스트럭터에서 작성된 ref는 기본 DOM 요소를 현재 속성으로 받습니다.
  2. ref 속성이 사용자 지정 클래스 구성 요소에 사용되는 경우 ref 개체는 현재 구성 요소의 마운트된 인스턴스를 수신합니다.
  3. 함수 구성 요소에는 인스턴스가 없으므로 ref 속성을 사용할 수 없습니다.

다양한 요소 유형에서 ref를 사용하는 방법의 예를 다음에 나타냅니다.

1. DOM 요소를 참조하면 DOM 노드 자체를 참조할 수 있습니다.

function AutoFocusInput() {
  const inputRef = useRef(null);
  // This effect runs only once after the component mounts (like componentDidMount)
  useEffect(() => {
    // refs on regular DOM elements (e.g. the "input" tag) have access to the DOM node
    inputRef.current.focus();
  }, []);
  return <input ref={inputRef} />
}

2. 클래스 컴포넌트를 참조하면 인스턴스의 모든 메서드와 필드를 사용하여 인스턴스에 액세스할 수 있습니다.

class Child extends Component {
  state = {color: "red"}
  toggleColor = () => this.setState({color: this.state.color === "red" ? "blue" : "red"})
  render() {
    return <div style={{backgroundColor: this.state.color}}>yo</div>
  }
}

class Parent extends Component {
  childRef = createRef();
  handleButtonClicked = () => {
    // refs on class components: hold the class component instance, 
    // allowing us to call its methods!
    this.childRef.current.toggleColor();
  }
  render() {
    return (
      <div>
        <button onClick={this.handleButtonClicked}>toggle color!</button>
        <Child ref={childRef} />
      </div>
    );
  }
}

3. 마지막으로 질문에 답하겠습니다.함수 구성 요소에는 인스턴스가 없으므로 참조를 전달할 수 없습니다.

함수 컴포넌트에 ref를 전달하는 유일한 방법은 forwardRef를 사용하는 것입니다.forwardRef를 사용하는 경우 참조를 DOM 요소에 전달하기만 하면 부모가 예 1과 같이 액세스 할 수 있습니다.또한 useImperativeHandle 후크를 사용하여 필드 및 메서드를 가진 개체를 만들 수도 있습니다.이러한 오브젝트는 예 2와 같습니다.

3.1 참조를 DOM 요소에 전달하기만 하면:

// Only when using forwardRef, the function component receives two arguments, 
// props and ref (Normally the component only gets the props argument).
const RedInput = forwardRef((props, ref) => {
  // passing the ref to a DOM element, 
  // so that the parent has a reference to the DOM node
  return <input style={{color: "red"}} {...props} ref={ref} />
});

function AutoFocusInput() {
  const inputRef = useRef(null);
  // This effect runs only once after the component mounts (like componentDidMount)
  useEffect(() => {
    // ref on function component is forwarded to a regular DOM element, 
    // so now the parent has access to the DOM node including its focus method.
    // Note that the ref usage is the same as a regular 
    // DOM element, like in example 1!
    inputRef.current.focus();
  }, []);
  return <RedInput ref={inputRef} />
}

3.2 커스텀 오브젝트에 parent ref 부착:

클래스 컴포넌트의 인스턴스처럼 함수 또는 필드를 ref에 연결하려면 "use Imperative Handle" 후크를 사용해야 합니다.

const Child = forwardRef((props, ref) => {
  const [color, setColor] = useState("red");
  // To customize the value that the parent will get in their ref.current: 
  // pass the ref object to useImperativeHandle as the first argument. 
  // Then, whatever will be returned from the callback in the second argument, 
  // will be the value of ref.current. 
  // Here I return an object with the toggleColor method on it, for the parent to use:
  useImperativeHandle(ref, () => ({
    toggleColor: () => setColor(prevColor => prevColor === "red" ? "blue" : "red")
  }));
  return <div style={{backgroundColor: color}}>yo</div>;
});


class Parent extends Component {
  childRef = createRef();
  handleButtonClicked = () => {
    // Ref passed to a function component wrapped in forwardRef.
    // Note that nothing has changed for this Parent component
    // compared with the class component in example 2!
    this.childRef.current.toggleColor();
  }
  render() {
    return (
      <div>
        <button onClick={this.handleButtonClicked}>toggle color!</button>
        <Child ref={childRef} />
      </div>
    );
  }
}

리액션 의사가 잘 설명해 줍니다.

https://reactjs.org/docs/forwarding-refs.html

React.forwardRef로 컴포넌트를 랩하고 ref를 원하는 DOM 요소로 설정합니다.

 const FancyButton = React.forwardRef((props,ref)=>(
      <button ref={ref} className="FancyButton">
         {props.children}
      </button>)
   );

언급URL : https://stackoverflow.com/questions/66664209/how-can-i-use-forwardref-in-react

반응형