# Refs 转发

* Ref 转发是一项将 ref 自动地通过组件传递到其一子组件的技巧

## 转发 Refs 到 DOM 组件

\`\`\`jsx harmony

function FancyButton(props) { return (  {props.children} ) }

````
* React 组件隐藏其实现细节，包括其渲染结果
    * 使用 FancyButton 的组件通常不需要获取内部的 DOM 元素 button 的 ref 这可以防止组件过度依赖其他组件的 DOM 结构
    * 但是这种封装对高复用的 叶 组件来说是不方便的，这些组件倾向于在整个应用中以一种类似常规 DOM button 和 input 的方式被使用 并且访问其 DOM 节点对管理焦点，选中或动画来说是不可避免的

* Refs 转发是一个可选特性，其允许某些组件接收 ref，并将其向下传递给子组件

```jsx harmony

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

// 你可以直接获取 DOM button 的 ref
const ref = React.createRef();
<FancyButton ref={ref}>
    Click me!
</FancyButton>
````

* FancyButton 使用 React.forwardRef 来获取传递给它的 ref，然后转发到它渲染的 DOM button
* 逐步解释：
  * 通过 React.crateRef 创建了一个 React ref 并将其赋值给 ref 变量
  * 指定 ref 为 JSX 属性，将其向下传递给 `<FancyButton ref={ref}>`
  * React 传递 ref 给 forwardRef 内函数 (props, ref) => ... 作为第二个参数
  * 向下转发 ref 参数到 `<button ref={ref}>`，将其指定为 JSX 属性
  * 当 ref 挂载完成，ref.current 将指向 button DOM 节点
* 第二个参数 ref 只有在使用 React.forwardRef 定义组件时存在，常规函数 和 class组件不接收 ref 参数，且 props 中也不存在 ref

## 组件库维护者的注意事项

* 当你开始在组件库中使用 forwardRef 时，你应当将其视为一个破坏性更改
  * 因为你的库可能会有明显不同的行为
  * 这样可能会导致依赖旧行为的应用和其他库崩溃

## 在高阶组件 HOC 中转发 refs

\`\`\`jsx harmony

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;

  // 将自定义的 prop 属性 “forwardedRef” 定义为 ref
  return <Component ref={forwardedRef} {...rest} />;
}
```

}

// 注意 React.forwardRef 回调的第二个参数 “ref”。 // 我们可以将其作为常规 prop 属性传递给 LogProps，例如 “forwardedRef” // 然后它就可以被挂载到被 LogProps 包裹的子组件上。 return React.forwardRef((props, ref) => { return ; }); }

\`\`\`


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://zg-zhang.gitbook.io/note/react/offical-website/advanced-guides/forwarding-refs.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
