理解 React 中 useRef hook 和 forwardRef 的用法
React 中的useRef hook 用于创建对 HTML 元素的引用。最常见的应用场景是当我们有表单元素,需要引用这些表单元素来打印它们的值或获取它们的焦点等。
因此,{useRef} hook 与其他 react hook 一样,是从“react”导入的,我们在函数组件中使用它们来创建引用,并且可以通过使用“ref”属性将其分配给jsx中的 html 元素。
下面展示了如何使用useRef钩子函数——
import React, { useEffect, useRef } from "react";
const UseRefHookExplained = (props) => {
// Creating refs for username and password
const userNameRef = useRef(null);
const passwordRef = useRef(null);
// We are also creating a reference to the Login button
const submitBtnRef = useRef(null);
// useEffect to set the initial focus to the user name input
useEffect(() => {
userNameRef.current.focus();
}, []);
// This function is used to handle the key press.
// Whenever user hits enter it moves to the next element
const handleKeyPress = (e, inputType) => {
if (e.key === "Enter") {
switch (inputType) {
// Checks if Enter pressed from the username field?
case "username":
// Moves the focus to the password input field
passwordRef.current.focus();
break;
// Checks if Enter pressed from the password field?
case "password":
// Moves the focus to the submit button
submitBtnRef.current.focus();
e.preventDefault();
break;
default:
break;
}
}
};
// Function to handle the submit click from the button
const handleSubmit = () => {
alert("submitted");
};
// getting the style as prop from the parent.
// Basic style to center the element and apply a bg color
const { style } = props;
return (
<div style={style}>
<h2>Example for using useRef Hook</h2>
<h3>Login</h3>
<input
type="text"
name="username"
ref={userNameRef}
onKeyDown={(e) => handleKeyPress(e, "username")}
/>
<input
type="password"
name="password"
ref={passwordRef}
onKeyDown={(e) => handleKeyPress(e, "password")}
/>
<button ref={submitBtnRef} onClick={handleSubmit}>
Login
</button>
</div>
);
};
export default UseRefHookExplained;
因此, useRef hook的概念非常简单,正如您在上面的代码中看到的那样。请按照以下步骤操作 -
- 我们从 React 导入 useRef hook。
- 我们初始化这个钩子(例如:const inputRef = useRef(null))
- 创建的引用通过“ref”属性附加到html元素上。
现在我们可以随时引用这个元素,以便进行诸如获取值、聚焦等操作。
输入密码并点击“确认”后,焦点状态转移到按钮上。
所以,现在这一点应该很清楚了。接下来,我们来看一个使用另一个 React 组件作为输入的场景。
在这种情况下,将我们在父组件中定义的引用作为属性传递给子组件(输入组件)就变得有点困难了。
React 提供了一种处理这种情况的方法,即使用React.forwardRef将 refs 转发给子组件。
让我们查看示例代码以了解更改之处——
(我添加了注释“//new”来标识新添加的代码行)
import React, { useEffect, useRef } from "react";
import Input from "./Input"; // new
const UseRefHookExplained = (props) => {
// Creating refs for username and password
const userNameRef = useRef(null);
const passwordRef = useRef(null);
// We are also creating a reference to the Login button
const submitBtnRef = useRef(null);
// useEffect to set the initial focus to the user name input
useEffect(() => {
userNameRef.current.focus();
}, []);
// This function is used to handle the key press.
// Whenever user hits enter it moves to the next element
const handleKeyPress = (e, inputType) => {
if (e.key === "Enter") {
switch (inputType) {
// Checks if Enter pressed from the username field?
case "username":
// Moves the focus to the password input field
passwordRef.current.focus();
break;
// Checks if Enter pressed from the password field?
case "password":
// Moves the focus to the submit button
submitBtnRef.current.focus();
e.preventDefault();
break;
default:
break;
}
}
};
// Function to handle the submit click from the button
const handleSubmit = () => {
alert("submitted");
};
// getting the style as prop from the parent.
// Basic style to center the element and apply a bg color
const { style } = props;
return (
<div style={style}>
<h2>Example for using useRef Hook</h2>
<h3>Login</h3>
{/* New. Using the Component instead of input element */}
<Input
type="text"
name="username"
ref={userNameRef}
onKeyDown={(e) => handleKeyPress(e, "username")}
/>
{/* New. Using the Component instead of input element */}
<Input
type="password"
name="password"
ref={passwordRef}
onKeyDown={(e) => handleKeyPress(e, "password")}
/>
<button ref={submitBtnRef} onClick={handleSubmit}>
Login
</button>
</div>
);
};
export default UseRefHookExplained;
现在我们来看一下 Input.js 组件。
import React from "react";
/* In the functional component, a second argument
is passed called ref, which will have access to
the refs being forwarded from the parent */
const Input = (props, ref) => {
/* assigning the ref attribute in input and spreading
the other props which will contain type, name, onkeydown etc */
return <input {...props} ref={ref} />;
};
// wrapping the Input component with forwardRef
const forwardedRef = React.forwardRef(Input);
// Exporting the wrapped component
export default forwardedRef;
因此,React.forwardRed 为我们提供了一种方法,使我们能够将父组件中定义的 refs 传递或转发到子组件。
希望你今天学到了新知识!
文章来源:https://dev.to/sajithpradeep/understanding-the-use-of-useeffect-hook-forwardref-in-react-57jf


