在React Native中Refs的用途是什么
Refs可以用于访问在render方法中创建的DOM节点或React Native组件。
我们可以使用Refs来获取React Native组件,并借助 useRef hook返回一个 ref对象 来实现。该对象具有一个 .current 属性,通过它可以访问React Native组件。
返回的对象将在整个组件的生命周期内保持持久。这意味着无论何时更新ref对象,都 不会导致组件重新渲染 。
这对于保留任何 可变值 很有帮助,就像在类中使用实例字段一样。
让我们通过一个示例来帮助您理解它:
创建应用程序: 按照以下步骤创建一个React Native应用程序:
步骤1: 打开终端并按照以下命令安装expo-cli。
npm install -g expo-cli
步骤2: 现在通过以下命令创建一个项目。
expo init Project
步骤3: 现在进入你的项目文件夹,即Project
cd Project
项目结构:
示例1: 在这个示例中,我们将使用ref来创建一个按钮,当点击按钮时,焦点应转移到TextInput组件上。
在 App.js 中,我们首先从 ‘react’ 中导入 useRef 钩子。然后,在组件内部,我们使用useRef创建一个名为 textRef 的ref对象。
点击按钮将调用 createFocusOnTextInput() 函数,该函数将使焦点转移到TextInput组件上。在此函数中,我们使用 .current属性 来访问组件。
App.js
import { useState, useRef } from 'react';
import { Text, View, StyleSheet, TextInput, Button }
from 'react-native';
export default function App() {
const [name, setName] = useState("")
// Creating a ref Object using useRef Hook
const textRef = useRef()
// Function to shift focus on TextInput component
function createFocusOnTextInput() {
textRef.current.focus();
}
return (
<View style={styles.container}>
<TextInput
// Creating reference to the TextInput component
ref={textRef}
onChangeText={text => setName(text)}
style={styles.input}
/>
<Text style={styles.text}>My Name is {name}</Text>
<Button
onPress={createFocusOnTextInput}
title="Focus On Text Input Component"
/>
</View>
);
}
// Styles for Text and View components
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#72e6e8',
padding: 8,
color: 'white'
},
input: {
height: 40,
width: 300,
margin: 12,
borderWidth: 3,
color: '#000000',
padding: 10,
},
text: {
margin: 14,
fontSize: 20,
fontWeight: 'bold',
textAlign: 'center',
color: 'white',
},
});
运行应用程序的步骤: 打开终端并输入以下命令。
npm start
输出:
如你在输出中可以看到的。按下按钮后,焦点会转移到TextInput组件。useRef的另一个用途是显示组件在屏幕上重新渲染的次数。
示例2: 在下面的示例中,我们创建了一个 文本输入框 并将其值显示在 文本组件 中。每当我们在文本输入框中键入某些内容时,它会触发一个事件,该事件会更新 name 状态。状态值变化后,组件会重新渲染。我们的目标是计算组件重新渲染的次数。因此,我们通过递增 renderCount.current 来更新它。此更新永远不会导致组件重新渲染,因为它与组件的渲染周期完全分离。
App.js
import { useState, useEffect, useRef } from 'react';
import { Text, View, StyleSheet, TextInput }
from 'react-native';
export default function App() {
const [name, setName] = useState('')
const renderCount = useRef(0)
// It's an object with current property {current: 0}
useEffect(() => {
// Updating the counter value on each re-render
renderCount.current = renderCount.current + 1
})
return (
<View style={styles.container}>
<TextInput
onChangeText={text => setName(text)}
style={styles.input}
/>
<Text style={styles.text}>My Name is {name}</Text>
<Text style={styles.text}>
I rendered {renderCount.current} times
</Text>
</View>
);
}
// Styles for Text and View components
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#72e6e8',
padding: 8,
color: 'white'
},
input: {
height: 40,
width: 300,
margin: 12,
borderWidth: 3,
color: '#000000',
padding: 10,
},
text: {
margin: 14,
fontSize: 20,
fontWeight: 'bold',
textAlign: 'center',
color: 'white',
},
});
如何运行应用程序的步骤: 打开终端并输入以下命令。
npm start
输出:
如您在输出中所见,一旦TextInput中的值发生更改,name值就会被重新渲染,并且renderCount会同时递增。
为什么我们不能使用简单的UseState钩子来计算重新渲染次数,而不是使用UseRef?
这是因为当组件首次渲染时,它将改变renderCount状态,从而导致重新渲染,然后更新该状态并再次推动组件重新渲染,这样循环下去,形成一个无限循环。这是因为useState钩子在渲染之间不保留值。在函数式组件中,如果没有useRef,我们无法使用useState来保留状态值。