useNavigationState
useNavigationState
是一个钩子,可以访问包含屏幕的导航器的 导航状态。在极少数情况下,你想要根据导航状态渲染某些内容,它非常有用。
¥useNavigationState
is a hook which gives access to the navigation state of the navigator which contains the screen. It's useful in rare cases where you want to render something based on the navigation state.
将导航器的状态对象视为内部对象,并且可能会在次要版本中发生更改。避免使用除 index
和 routes
之外的 导航状态 状态对象的属性,除非你确实需要它。如果某些功能在不依赖状态对象的结构的情况下无法实现,请提出问题。
¥Consider the navigator's state object to be internal and subject to change in a minor release. Avoid using properties from the navigation state state object except index
and routes
, unless you really need it. If there is some functionality you cannot achieve without relying on the structure of the state object, please open an issue.
它采用选择器函数作为参数。选择器将接收完整的 导航状态 并可以从状态返回特定值:
¥It takes a selector function as an argument. The selector will receive the full navigation state and can return a specific value from the state:
const index = useNavigationState((state) => state.index);
选择器功能有助于减少不必要的重新渲染,因此只有当你关心的事情时,你的屏幕才会重新渲染。如果你确实需要整个状态对象,你可以明确地执行此操作:
¥The selector function helps to reduce unnecessary re-renders, so your screen will re-render only when that's something you care about. If you actually need the whole state object, you can do this explicitly:
const state = useNavigationState((state) => state);
这个钩子对于高级情况很有用,如果你不小心,很容易引入性能问题。对于大多数情况,你不需要导航器的状态。
¥This hook is useful for advanced cases and it's easy to introduce performance issues if you're not careful. For most of the cases, you don't need the navigator's state.
useNavigationState
与 navigation.getState()
有何不同?
¥How is useNavigationState
different from navigation.getState()
?
navigation.getState()
函数还返回当前的 导航状态。主要区别在于 useNavigationState
钩子会在值更改时触发重新渲染,而 navigation.getState()
不会。例如,以下代码将是错误的:
¥The navigation.getState()
function also returns the current navigation state. The main difference is that the useNavigationState
hook will trigger a re-render when values change, while navigation.getState()
won't. For example, the following code will be incorrect:
function Profile() {
const routesLength = navigation.getState().routes.length; // Don't do this
return <Text>Number of routes: {routesLength}</Text>;
}
在此示例中,即使你推送新屏幕,此文本也不会更新。如果你使用钩子,它将按预期工作:
¥In this example, even if you push a new screen, this text won't update. If you use the hook, it'll work as expected:
- Static
- Dynamic
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()
呢?它在事件监听器中最有用,你不关心渲染的内容。在大多数情况下,应优先使用钩子。
¥So when do you use navigation.getState()
? It's mostly useful within event listeners where you don't care about what's rendered. In most cases, using the hook should be preferred.
与类组件一起使用
¥Using with class component
你可以将类组件封装在函数组件中以使用钩子:
¥You can wrap your class component in a function component to use the 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} />;
}