ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# Refs 和 DOM 在典型的 React 数据流中,[props](https://facebook.github.io/react/docs/components-and-props.html) 是父组件影响子组件的唯一方式。要修改一个子组件,可以使用新的 props 重新渲染它。然而,有一些情况你需要在典型的数据流之外命令式修改一个子组件。要被修改的子组件应该是一个 React 组件的实例,或者它应该是一个 DOM 元素。这两种情况,React 提供了一个 安全舱。 ## ref 回调属性 React 支持一个特定的属性,你可以用来连接到任何组件。ref 属性带有一个回调函数,回调函数在组件被装载或者卸载之后立即执行。 当 ref 属性用于在一个 HTML 元素上,ref 回调接受底层的 DOM 元素作为它的参数。例如,这段代码使用了 ref 回调来存储一个 对于 一个 DOM 节点的引用: ~~~ class CustomTextInput extends React.Component { constructor(props) { super(props); this.focus = this.focus.bind(this); } focus() { // Explicitly focus the text input using the raw DOM API this.textInput.focus(); } render() { // Use the `ref` callback to store a reference to the text input DOM // element in this.textInput. return ( <div> <input type="text" ref={(input) => { this.textInput = input; }} /> <input type="button" value="Focus the text input" onClick={this.focus} /> </div> ); } } ~~~ 当组件被安装后,React 将会在 DOM 元素上调用 ref 回调,并在组件卸载时传递 null 进行调用。 使用 ref 回调只要设置类的属性为一个一般模式来访问 DOM 元素。如果你正确的使用 this.refs.myRefName 来访问 refs,我们建议使用 这个模式替代。 当 ref 属性用在一个自定义组件上,ref 回调接受安装的组件实例作为它的参数。例如,如果我们想要包装 CustomTextInput 来模拟它在装载之后立即被点击: ~~~ class AutoFocusTextInput extends React.Component { componentDidMount() { this.textInput.focus(); } render() { return ( <CustomTextInput ref={(input) => { this.textInput = input; }} /> ); } } ~~~ 你不能使用 ref 属性在功能组件上,因为它们没有实例。然而,你可以使用 ref 属性在一个功能组件的 render 函数中: ~~~ function CustomTextInput(props) { // textInput must be declared here so the ref callback can refer to it let textInput = null; function handleClick() { textInput.focus(); } return ( <div> <input type="text" ref={(input) => { textInput = input; }} /> <input type="button" value="Focus the text input" onClick={handleClick} /> </div> ); } ~~~ ## 不要过度使用 refs 你首先的倾向可能是用 refs 来”使某事情发生“。如果说这个情况,用一些时间思考,关于 state 应该被在组件层级中的哪里拥有。通常,适当的位置拥有 state 是在一个更高的层级上,将变得清晰。查看[状态提升](https://facebook.github.io/react/docs/lifting-state-up.html)中关于这个的例子。