react-native - react-navigation:检测屏幕,标签栏何时激活/出现/聚焦/模糊
问题描述
以前当我想在屏幕打开时做一些动作时,我把它们放在里面componentDidMount
。例如,我可以获取一些数据。
像这样。
componentDidMount() {
this.updateData();
}
但是react-navigation
componentDidMount
当用户第一次打开屏幕时只发生一次,如果以后用户再次打开这个页面,它不会触发componentDidMount。
检测页面(屏幕)何时激活并执行操作的正确方法是什么?
解决方案
反应导航 v6
当屏幕成为焦点时使用 API 调用获取数据
React Navigation 提供了一个钩子,当屏幕聚焦时运行效果并在失焦时清理它。这对于添加事件侦听器、在屏幕成为焦点时通过 API 调用获取数据或屏幕进入视图后需要执行的任何其他操作等情况很有用。
import { useFocusEffect } from '@react-navigation/native';
function ProfileScreen() {
useFocusEffect(
React.useCallback(() => {
alert('Screen was focused');
return () => {
alert('Screen was unfocused');
// Useful for cleanup functions
};
}, [])
);
return <View />;
}
一个布尔值,指示屏幕是否聚焦
React Navigation 提供了一个钩子,它返回一个布尔值,指示屏幕是否聚焦。当屏幕聚焦时,钩子将返回 true,当我们的组件不再聚焦时,钩子将返回 false。这使我们能够根据用户是否在屏幕上来有条件地渲染某些东西。
import { useIsFocused } from '@react-navigation/native';
function Profile() {
const isFocused = useIsFocused();
return <Text>{isFocused ? 'focused' : 'unfocused'}</Text>;
}
参考 v6.x:https ://reactnavigation.org/docs/function-after-focusing-screen/
年长者:
使用react-navigation
,您可以分两步完成:
componentDidMount
在or中添加侦听componentWillMount
器以挂钩事件删除监听
componentWillUnmount
器,避免意外调用
API 参考文档 v3.x、v4.x、v5.x
反应导航 v3.x、v4.x:
addListener
- 订阅导航生命周期的更新React Navigation 向订阅它们的屏幕组件发出事件:
willFocus
- 屏幕将聚焦didFocus
- 屏幕聚焦(如果有过渡,则过渡完成)willBlur
- 屏幕将不聚焦didBlur
- 屏幕失焦(如果有过渡,则过渡完成)
React-navigation 3.x、4.x示例:
const didBlurSubscription = this.props.navigation.addListener(
'didBlur',
payload => {
console.debug('didBlur', payload);
}
);
// Remove the listener when you are done
didBlurSubscription.remove();
更新的 v5.x
v5.x 中的事件已更改
屏幕可以像在 React Navigation 中一样在导航道具上添加侦听器。默认情况下,有 2 个事件可用:
- focus - 当屏幕成为焦点时发出此事件
- blur - 当屏幕失焦时发出此事件
- state (advanced) - 当导航器的状态改变时触发此事件
来自 reactnavigation.org 的示例代码
class Profile extends React.Component {
componentDidMount() {
this._unsubscribe = navigation.addListener('focus', () => {
// do something
});
}
componentWillUnmount() {
this._unsubscribe();
}
render() {
// Content of the component
}
}
与钩子一起使用
function Profile({ navigation }) {
React.useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
// do something
});
return unsubscribe;
}, [navigation]);
return <ProfileContent />;
}
屏幕上的听众道具
<Tab.Screen
name="Chat"
component={Chat}
listeners={({ navigation, route }) => ({
tabPress: e => {
// Prevent default action
e.preventDefault();
// Do something with the `navigation` object
navigation.navigate('AnotherPlace');
},
})}
/>
推荐阅读
- angular - Angular - 与同一路径的子路径关联的两个不同的延迟加载模块
- android - 如何将共享首选项从一项活动传递到另一项活动?
- angular - 在 TypeScript 中创建 const 对象的问题
- python-3.x - 即使 numpy 数据形状正确,skLearn 拟合数据输入也会失败
- visual-studio-code - 如何在 VS Code 工作区设置中使用 ${workspaceFolder}?
- javascript - Vue JS中的等号“=”和冒号“:”有什么区别?
- python-3.x - 文本换行忽略标题行
- c++ - 如何从 std::vector 中擦除元素
按其长度(擦除不起作用) - android - 处理房间内的异常
- c# - AWS Lambda 函数增加 Max Memory Used