【发布时间】:2017-10-19 00:00:37
【问题描述】:
我无法理解 React 中的 refs 是什么。我知道这是一个回调函数,你把它放在渲染函数中,但除此之外我无法理解它是什么以及它的目的是什么。
【问题讨论】:
标签: reactjs
我无法理解 React 中的 refs 是什么。我知道这是一个回调函数,你把它放在渲染函数中,但除此之外我无法理解它是什么以及它的目的是什么。
【问题讨论】:
标签: reactjs
Refs 是您获取已创建组件的句柄的一种方式。
即。
<Text ref={(component)=>{this.textComponent = component}} > Here is some Text</Text>
然后在您的代码中,您可以通过以下方式访问您的文本:
this.textComponent
这将使您能够以面向对象的方式调用组件上的函数。
我只想指出,React/React-Native 使用声明式编程范式,其中数据和“控制”通过自上而下的属性通道进行管理。而在命令式风格中,您处理对象和指针并传递它们以便在它们上调用函数。在这种情况下,Refs 是一个逃生舱口,它允许您获取已声明的组件,以便您可以以命令式样式调用它们的函数。
请参阅官方 React 文档以获取 refs: https://reactjs.org/docs/refs-and-the-dom.html
【讨论】:
<input>这样的“原生”元素,它会反馈给你一个DOMElement,这样你就可以做getBoundingClientRect或focus()这样的事情,这通常是我有过的使用它。
React 有典型的处理孩子的方式。它以自上而下的方式使用props 来实现。并且要修改孩子,您必须使用新道具重新渲染。但是在某些情况下,您希望在此典型流程之外修改/处理子项。在这些情况下,您使用 refs。
Ref 是一个接受回调的属性,每当组件被挂载或卸载时都会调用此回调。 Refs 可以添加到 dom 元素或组件中。示例:
return (
<div>
<input
type="text"
// ref to a dom element
ref={(input) => { this.textInput = input; }} />
</div>
);
return (
<MyComponent
// ref to a MyComponent(child component)
ref={(component) => { this.childComponent = component; }}
{...props}
/>
);
每当安装组件时,都会使用 dom 元素或子组件实例调用 ref 回调。并且每当卸载组件时,都会使用null 调用它。
现在您可以使用this.textInput 或this.childComponent 并在其上调用其不同的可用方法。
Refs 只能赋予 DOM 元素或类组件。它们不适用于功能组件。示例:
function MyFunctionalComponent(props) {
return <input type="text" />;
}
return (
<MyFunctionalComponent
// This won't work
ref={(component) => { this.childComponent = component; }}
{...props}
/>
);
只有在绝对必要时才应该使用 Refs,因为它们可以让您直接访问 DOM 中的元素/组件。
【讨论】:
Refs 是一种在 DOM 元素或类组件实例中设置变量的方法。
有两种类型的引用:回调引用和对象引用。
对象引用是使用useRef() 或React.createRef() 创建的。
使用它们(函数组件引用 DOM 元素的示例):
声明一个“容器”变量(您将在下一步中指向一个 DOM 元素)并将其设置为等于useRef()。这是您的“参考对象”。
为您的 DOM 元素添加 ref 属性。将其设置为等于您的 ref 对象。
现在这个ref 对象代表你指向它的DOM 元素,并且可以用来访问它的方法和属性。
function InputField() {
const refForInput = useRef(); // 1. initializing `refForInput` as a reference object.
return (
<div>
<input type='text' ref={refForInput} /> //2. passing it to the input element as its ref
<button onClick={() => refForInput.current.focus()}>Click to focus the input field</button> // 3. now, calling `refForInput` will refer to the DOM <input> element, and you can access its `focus()` method.
</div>
)
}
如果使用类组件,过程类似;详情请见React docs。
回调 refs 功能类似,但允许更细粒度的控制。
要创建回调 ref,您同样需要向 DOM 元素添加 ref 属性,但不是传入 ref 对象,而是传入回调。这个回调接收元素本身作为回调的参数;然后,您可以将其设置为等于现有值(类中的this.something;函数组件中已声明的变量。)
这是来自 Avid Programmer 的优秀示例的示例的注释版本;请参阅他的答案以获取有关课程的示例。
function CustomForm({handleSubmit}) {
let inputElement;
return (
<form onSubmit={() => handleSubmit(inputElement.value)}> // 2. Now, this refers to the `value` of the `<input>` element just below.
<input
type='text'
ref={(input) => inputElement = input} // 1. so, here, `input` in the callback refers to the DOM element. Now, when the component mounts, `inputElement` will *reference* this DOM <input> element.
/>
<button type='submit'>Submit</button>
</form>
)
}
请注意,当组件卸载时,回调将使用null 调用。
它们不应该经常使用;他们的意思是作为逃生舱口。它们允许您访问在 React 组件上可能不可用的实际 html 元素上可用的 API 方法(focus() 是一个常见示例)。如果这看起来令人困惑,请记住,例如,React 按钮组件与 html 按钮组件不同。您可以在 html 按钮元素上调用 focus(),但不能在 React 按钮元素上调用。
【讨论】:
Refs 是一个逃生舱口,它允许您直接访问 DOM 元素或组件的实例。为了使用它们,你需要为你的组件添加一个 ref 属性,它的值是一个回调函数,它将接收底层 DOM 元素或组件的挂载实例作为它的第一个参数。
class UnControlledForm extends Component {
handleSubmit = () => {
console.log("Input Value: ", this.input.value)
}
render () {
return (
<form onSubmit={this.handleSubmit}>
<input
type='text'
ref={(input) => this.input = input} />
<button type='submit'>Submit</button>
</form>
)
}
}
通过利用 JavaScript 中的闭包,refs 也可以与功能组件一起使用。
function CustomForm ({handleSubmit}) {
let inputElement
return (
<form onSubmit={() => handleSubmit(inputElement.value)}>
<input
type='text'
ref={(input) => inputElement = input} />
<button type='submit'>Submit</button>
</form>
)
}
(“闭包”只是一种奇特的说法,它引用了在函数外部声明的变量 - 在这种情况下,inputElement - 在你的函数中,在这种情况下是 ref={(input) => inputElement = input}。)
【讨论】:
inputElement 是在CustomForm 内部声明的,而不是在其外部。