跳到主要内容
版本:7.x

useNavigationState

useNavigationState 是一个 Hook,它可以访问包含屏幕的导航器的导航状态。在极少数情况下,当您想要根据导航状态渲染某些内容时,它非常有用。

警告

请将导航器的状态对象视为内部对象,并且可能会在小版本更新中发生更改。除非您真的需要,否则请避免使用导航状态状态对象中的属性,除了 indexroutes。 如果您有某些功能在不依赖状态对象的结构的情况下无法实现,请提交 issue。

它接受一个选择器函数作为参数。选择器将接收完整的导航状态,并且可以从状态中返回特定的值

const index = useNavigationState((state) => state.index);

选择器函数有助于减少不必要的重新渲染,因此您的屏幕仅在您关心的事情发生变化时才会重新渲染。如果您实际上需要整个状态对象,您可以显式地这样做

const state = useNavigationState((state) => state);
警告

这个 Hook 对于高级用例很有用,如果您不小心,很容易引入性能问题。在大多数情况下,您不需要导航器的状态。

useNavigationStatenavigation.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'
);
}
Snack 上尝试

那么,您何时使用 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} />;
}