useNavigationState
useNavigationState
是一个 Hook,它可以访问包含屏幕的导航器的导航状态。在极少数情况下,当您想要根据导航状态渲染某些内容时,它非常有用。
警告
请将导航器的状态对象视为内部对象,并且可能会在小版本更新中发生更改。除非您真的需要,否则请避免使用导航状态状态对象中的属性,除了 index
和 routes
。 如果您有某些功能在不依赖状态对象的结构的情况下无法实现,请提交 issue。
它接受一个选择器函数作为参数。选择器将接收完整的导航状态,并且可以从状态中返回特定的值
const index = useNavigationState((state) => state.index);
选择器函数有助于减少不必要的重新渲染,因此您的屏幕仅在您关心的事情发生变化时才会重新渲染。如果您实际上需要整个状态对象,您可以显式地这样做
const state = useNavigationState((state) => state);
警告
这个 Hook 对于高级用例很有用,如果您不小心,很容易引入性能问题。在大多数情况下,您不需要导航器的状态。
useNavigationState
与 navigation.getState()
有何不同?
navigation.getState()
函数也返回当前的导航状态。 主要区别在于,当值更改时,useNavigationState
Hook 将触发重新渲染,而 navigation.getState()
不会。 例如,以下代码将是不正确的
function Profile() {
const routesLength = navigation.getState().routes.length; // Don't do this
return <Text>Number of routes: {routesLength}</Text>;
}
在此示例中,即使您推送新屏幕,此文本也不会更新。 如果您使用 Hook,它将按预期工作
- 静态
- 动态
import { useNavigationState } from '@react-navigation/native';
function useIsFirstRouteInParent() {
const route = useRoute();
const isFirstRouteInParent = useNavigationState(
(state) => state.routes[0].key === route.key
);
return isFirstRouteInParent;
}
function usePreviousRouteName() {
return useNavigationState((state) =>
state.routes[state.index - 1]?.name
? state.routes[state.index - 1].name
: 'None'
);
}
import { useNavigationState } from '@react-navigation/native';
function useIsFirstRouteInParent() {
const route = useRoute();
const isFirstRouteInParent = useNavigationState(
(state) => state.routes[0].key === route.key
);
return isFirstRouteInParent;
}
function usePreviousRouteName() {
return useNavigationState((state) =>
state.routes[state.index - 1]?.name
? state.routes[state.index - 1].name
: 'None'
);
}
那么,您何时使用 navigation.getState()
呢? 它主要在事件监听器中很有用,在这些监听器中您不关心渲染的内容。 在大多数情况下,应首选使用 Hook。
与类组件一起使用
您可以将您的类组件包装在一个函数组件中以使用 Hook
class Profile extends React.Component {
render() {
// Get it from props
const { routesLength } = this.props;
}
}
// Wrap and export
export default function (props) {
const routesLength = useNavigationState((state) => state.routes.length);
return <Profile {...props} routesLength={routesLength} />;
}