CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-navigation--native

React Native integration for React Navigation providing navigation containers, deep linking, and platform-specific navigation behaviors.

Pending
Overview
Eval results
Files

navigation-hooks.mddocs/

Navigation Hooks

React hooks for programmatic navigation, link building, scroll management, and accessing navigation-related context information.

Capabilities

useLinkTo Hook

Returns a function to navigate using href-based paths.

/**
 * Helper to navigate to a screen using a href based on the linking options.
 * Throws error if used outside NavigationContainer.
 */
function useLinkTo(): (href: string) => void;

Usage Examples:

import { useLinkTo } from '@react-navigation/native';
import { Button } from 'react-native';

function NavigationButton() {
  const linkTo = useLinkTo();

  const handlePress = () => {
    linkTo('/profile/123');
  };

  return <Button title="Go to Profile" onPress={handlePress} />;
}

// Navigate with query parameters
function SearchButton() {
  const linkTo = useLinkTo();

  const performSearch = (query: string) => {
    linkTo(`/search?q=${encodeURIComponent(query)}`);
  };

  return (
    <Button 
      title="Search Products" 
      onPress={() => performSearch('react navigation')} 
    />
  );
}

// Conditional navigation
function ConditionalNavigation() {
  const linkTo = useLinkTo();

  const navigateToProfile = () => {
    if (userLoggedIn) {
      linkTo('/profile');
    } else {
      linkTo('/login');
    }
  };

  return <Button title="View Profile" onPress={navigateToProfile} />;
}

useLinkBuilder Hook

Provides utilities for building hrefs and actions from navigation parameters.

/**
 * Helpers to build href or action based on the linking options.
 * Returns buildHref to build an href for screen and buildAction to build an action from an href.
 */
function useLinkBuilder(): {
  /** Build an href for a screen name and parameters */
  buildHref: (name: string, params?: object) => string | undefined;
  /** Build a navigation action from an href */
  buildAction: (href: string) => NavigationAction;
};

Usage Examples:

import { useLinkBuilder } from '@react-navigation/native';
import { Share } from 'react-native';

function ShareableScreen() {
  const { buildHref } = useLinkBuilder();

  const shareCurrentScreen = async () => {
    const href = buildHref('CurrentScreen', { id: screenId });
    
    if (href) {
      await Share.share({
        message: `Check out this screen: https://myapp.com${href}`,
        url: `https://myapp.com${href}`,
      });
    }
  };

  return <Button title="Share" onPress={shareCurrentScreen} />;
}

// Build navigation actions
function CustomNavigationHandler() {
  const { buildAction } = useLinkBuilder();

  const handleDeepLink = (url: string) => {
    try {
      const action = buildAction(url);
      navigation.dispatch(action);
    } catch (error) {
      console.error('Invalid deep link:', url);
    }
  };

  // Used with custom URL handling logic
  return null;
}

// Generate links for different screens
function NavigationMenu() {
  const { buildHref } = useLinkBuilder();

  const menuItems = [
    { name: 'Home', screen: 'Home' },
    { name: 'Profile', screen: 'Profile', params: { userId: currentUser.id } },
    { name: 'Settings', screen: 'Settings' },
  ];

  return (
    <View>
      {menuItems.map((item) => {
        const href = buildHref(item.screen, item.params);
        return (
          <TouchableOpacity 
            key={item.name}
            onPress={() => linkTo(href)}
          >
            <Text>{item.name}</Text>
          </TouchableOpacity>
        );
      })}
    </View>
  );
}

useScrollToTop Hook

Automatically scrolls scrollable components to top when tab is pressed in tab navigators.

/**
 * Hook to automatically scroll to top when tab is pressed.
 * Must be used with a ref to a scrollable component.
 * Throws error if used outside NavigationContainer.
 */
function useScrollToTop(ref: React.RefObject<ScrollableWrapper>): void;

type ScrollableWrapper =
  | { scrollToTop(): void }
  | { scrollTo(options: { x?: number; y?: number; animated?: boolean }): void }
  | { scrollToOffset(options: { offset: number; animated?: boolean }): void }
  | { scrollResponderScrollTo(options: { x?: number; y?: number; animated?: boolean }): void }
  | { getScrollResponder(): React.ReactNode | ScrollView }
  | { getNode(): ScrollableWrapper }
  | null;

Usage Examples:

import { useScrollToTop } from '@react-navigation/native';
import { ScrollView, FlatList } from 'react-native';

// With ScrollView
function ScrollableScreen() {
  const scrollRef = useRef<ScrollView>(null);
  useScrollToTop(scrollRef);

  return (
    <ScrollView ref={scrollRef}>
      {/* Your scrollable content */}
    </ScrollView>
  );
}

// With FlatList
function ListScreen() {
  const listRef = useRef<FlatList>(null);
  useScrollToTop(listRef);

  return (
    <FlatList
      ref={listRef}
      data={items}
      renderItem={({ item }) => <ItemComponent item={item} />}
    />
  );
}

// With SectionList
function SectionListScreen() {
  const sectionListRef = useRef<SectionList>(null);
  useScrollToTop(sectionListRef);

  return (
    <SectionList
      ref={sectionListRef}
      sections={sections}
      renderItem={({ item }) => <ItemComponent item={item} />}
      renderSectionHeader={({ section }) => <HeaderComponent section={section} />}
    />
  );
}

// With custom scrollable component
function CustomScrollableScreen() {
  const customScrollRef = useRef<CustomScrollComponent>(null);
  useScrollToTop(customScrollRef);

  return (
    <CustomScrollComponent ref={customScrollRef}>
      {/* Content */}
    </CustomScrollComponent>
  );
}

// Multiple scrollable components
function MultiScrollScreen() {
  const primaryScrollRef = useRef<ScrollView>(null);
  const secondaryScrollRef = useRef<FlatList>(null);
  
  // Only attach to the primary scrollable component
  useScrollToTop(primaryScrollRef);

  return (
    <View>
      <ScrollView ref={primaryScrollRef}>
        {/* Primary content */}
      </ScrollView>
      <FlatList
        ref={secondaryScrollRef}
        data={items}
        renderItem={({ item }) => <Item item={item} />}
      />
    </View>
  );
}

useLocale Hook

Accesses the text direction specified in the NavigationContainer.

/**
 * Hook to access the text direction specified in the NavigationContainer.
 * Throws error if used outside NavigationContainer.
 */
function useLocale(): {
  /** Current text direction ('ltr' or 'rtl') */
  direction: LocaleDirection;
};

type LocaleDirection = 'ltr' | 'rtl';

Usage Examples:

import { useLocale } from '@react-navigation/native';
import { StyleSheet, View, Text } from 'react-native';

// Basic locale-aware styling
function LocaleAwareComponent() {
  const { direction } = useLocale();

  return (
    <View style={[
      styles.container,
      { flexDirection: direction === 'rtl' ? 'row-reverse' : 'row' }
    ]}>
      <Text>Content that respects text direction</Text>
    </View>
  );
}

// Conditional text alignment
function DirectionalText({ children }) {
  const { direction } = useLocale();

  return (
    <Text style={[
      styles.text,
      { textAlign: direction === 'rtl' ? 'right' : 'left' }
    ]}>
      {children}
    </Text>
  );
}

// Icon positioning based on direction
function IconWithText({ icon, text }) {
  const { direction } = useLocale();
  const isRTL = direction === 'rtl';

  return (
    <View style={[
      styles.iconContainer,
      { flexDirection: isRTL ? 'row-reverse' : 'row' }
    ]}>
      <Image source={icon} style={[
        styles.icon,
        { marginRight: isRTL ? 0 : 8, marginLeft: isRTL ? 8 : 0 }
      ]} />
      <Text>{text}</Text>
    </View>
  );
}

// Animation direction
function SlideAnimation({ children }) {
  const { direction } = useLocale();
  const slideDirection = direction === 'rtl' ? 'right' : 'left';

  return (
    <Animated.View style={[
      styles.animatedContainer,
      getSlideStyle(slideDirection)
    ]}>
      {children}
    </Animated.View>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 16,
  },
  text: {
    fontSize: 16,
  },
  iconContainer: {
    alignItems: 'center',
    padding: 12,
  },
  icon: {
    width: 24,
    height: 24,
  },
  animatedContainer: {
    flex: 1,
  },
});

Hook Error Handling

All navigation hooks require being used within a NavigationContainer and will throw descriptive errors when used outside the navigation context.

// Error thrown when hooks are used outside NavigationContainer
class NavigationError extends Error {
  message: "Couldn't find a navigation object. Is your component inside NavigationContainer?";
}

// Error thrown when buildAction receives invalid href
class LinkingError extends Error {
  message: "The href must start with '/' (provided_href).";
}

// Error thrown when parsing fails
class StateParsingError extends Error {
  message: "Failed to parse the href to a navigation state.";
}

Error Handling Examples:

// Safe hook usage with error boundaries
function SafeNavigationComponent() {
  try {
    const linkTo = useLinkTo();
    return <Button title="Navigate" onPress={() => linkTo('/home')} />;
  } catch (error) {
    console.error('Navigation hook error:', error);
    return <Text>Navigation not available</Text>;
  }
}

// Conditional hook usage
function ConditionalHookUsage({ hasNavigation }) {
  if (!hasNavigation) {
    return <Text>No navigation available</Text>;
  }

  // Hooks must still be called at the top level
  const linkTo = useLinkTo();
  return <Button title="Navigate" onPress={() => linkTo('/home')} />;
}

// Error boundary for navigation components
class NavigationErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    if (error.message.includes('navigation object')) {
      return { hasError: true };
    }
    return null;
  }

  render() {
    if (this.state.hasError) {
      return <Text>Navigation is not available in this context</Text>;
    }

    return this.props.children;
  }
}

Install with Tessl CLI

npx tessl i tessl/npm-react-navigation--native

docs

deep-linking.md

index.md

link-components.md

navigation-container.md

navigation-hooks.md

server-side-rendering.md

static-navigation.md

theming.md

tile.json