Giter VIP home page Giter VIP logo

hooks's Introduction

React Navigation 7

Build Status Code Coverage MIT License

Routing and navigation for your React Native apps.

Documentation can be found at reactnavigation.org.

This branch contains the code for the pre-release version of React Navigation 7. You can find the code for the latest stable version in the 6.x branch.

Package Versions

Name Latest Version
@react-navigation/bottom-tabs badge
@react-navigation/core badge
@react-navigation/devtools badge
@react-navigation/drawer badge
@react-navigation/elements badge
@react-navigation/material-top-tabs badge
@react-navigation/native-stack badge
@react-navigation/native badge
@react-navigation/routers badge
@react-navigation/stack badge
react-native-tab-view badge

Contributing

Please read through our contribution guide to get started!

Installing from a fork on GitHub

Since we use a monorepo, it's not possible to install a package from the repository URL. If you need to install a forked version from Git, you can use gitpkg.

First install gitpkg:

yarn global add gitpkg

Then follow these steps to publish and install a forked package:

  1. Fork this repo to your account and clone the forked repo to your local machine
  2. Open a Terminal and cd to the location of the cloned repo
  3. Run yarn to install any dependencies
  4. If you want to make any changes, make them and commit
  5. Run yarn lerna run prepack to perform the build steps
  6. Now cd to the package directory that you want to use (e.g. cd packages/stack for @react-navigation/stack)
  7. Run gitpkg publish to publish the package to your repo

After publishing, you should see something like this:

Package uploaded to [email protected]:<user>/<repo>.git with the name <name>

You can now install the dependency in your project:

yarn add <user>/<repo>.git#<name>

Remember to replace <user>, <repo> and <name> with right values.

hooks's People

Contributors

benseitz avatar bysabi avatar dependabot[bot] avatar ericvicenti avatar evancloutier avatar nem035 avatar nnals avatar slorber avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hooks's Issues

navigate.openDrawer is not a function

I am trying to change my react-navigation to hooks and navigating to pages using navigate("Page") works for but openDrawer does not:

 const { navigate } = useNavigation();
      return (
         <Button transparent onPress={() => navigate.openDrawer()}>
            <Icon active name="menu"/>
         </Button>
      )

image

Is this a bug in react-navigation hooks or am I doing something wrong?

react-navigation-hooks 1.0.1
doing this in react-native using expo 34

useFocusEffect should handle drawers

useFocusEffect will be called on Drawer everytime the app navigates to another route

I've fixed like this:

useEffect(() => {
    if (navigation.state.isDrawerOpen) {
      // handle navigation is open
    }
  }, [navigation.state?.isDrawerOpen]);

react-navigation-hooks v2

Issue to discuss what should be included in v2, including breaking changes.

Keep in mind this project is temporary and v5 will ship with hooks directly in core.

The goal for v2 is to try to avoid introducing any new hook that won't be in v5, as it would only make the v3/v4 => v5 migration more painful.

Implement basic test suite

A few tests should be able to cover this simple library. Most of this task is setting up jest properly, and the tests will be fairly easy to write

isFocused not updating after first navigation

I've tried both approaches and end up with the same result:

// 1. 
const { isFocused } = useNavigationFocus()

// 2. 
const navigation = useNavigation();
const isFocused = navigation.isFocused();

This is in the context of a Tab Navigator. The first time I switch tab isFocused is updated - but after the initial render it doesn't update.

For now I went back to use withNavigationFocus- I get a feeling this package needs some more testing before using! :)

useNavigationEvents will not trigger willFocus on second screen in StackNavigator

Suppose i have the following code, willBlur event will not be triggered for ScreenTwo.

const useCustomNavigationEventsHook = () => {
	useNavigationEvents(evt => {
		if(event === 'willFocus') {
			alert("Will Focus");
		} else if(event === 'willBlur') {
			alert("Will Blur");
		}
	})
}

const ScreenOne = () => {
	useCustomNavigationEventsHook();
	// alert Will Focus
	// Navigates to ScreenTwo
	// alert Will Blur
}

const ScreenTwo = () => {
	useCustomNavigationEventsHook();
	// alert Will Focus will not be triggered here
}

However, if I move the navigation.addListener('willFocus') outside of useEffect like the following, it seems to be working fine for both screens.

const useNavigationEvents = handler => {
	const subsWFRef = useRef(null);
	if(!subsWFRef.current) {
		subsWFRef.current = navigation.addListener('willFocus', handler);
	}
	
	useEffect(() => {
		// This chunk is prob not necessary as we're already adding the listener synchronously above
		if(!subsWFRef.current) {
			subsWFRef.current = navigation.addListener('willFocus', handler);
		}
		// Other subscriptions
		
		return () => {
			subsWFRef.current.remove();
			subsWFRef.current = null;
			// Remove other subscriptions
		}
	}, 
	// Existing deps
	)
}

iOS swipe back event

I am currently using useFocusState to configure parts of my screens when the screen focuses or isFocusing. It does not get triggered if the user swipes back though.

useFocusEffect should not retrigger on re-render

Reported by in https://github.com/react-navigation/hooks/pull/43/files#r334335721 by @ArrayZoneYour

The following code is likely to produce an infinite loop, even if we make sure the dependency is stable using a ref, because useFocusEffect use "navigation" as a dependency and the object is unstable.

useFocusEffect(useCallback(() => { 
  setParamsRef.current({});
},[setParamsRef])); 

The focus effect might retrigger unnecessarily due to the navigation being unstable

Somehow this is related to #40

@satya164 what do you think about using a useNavigationRef hook as you suggested in some other issue? Didn't get a clear answer from the React team on how to handle this kind of situation but that should work. Or maybe I should depend only on isFocused and addListener which are the only 2 fn used, but if core does not guarantee stability across render the problem remains.

navigationOptions not working correctly

I've noticed that for some reason navigationOptions aren't set correctly when using useEffect to initialize them when component mounts.

Here's a basic test scenario to reproduce this:

function TestScreen() {
  const navigation = useNavigation();

  useEffect(() => {
    console.log('component did mount');
    navigation.setParams({
      test: true,
    });
  }, []);

  return null;
}

TestScreen.navigationOptions = (screenProps) => {
  console.log('navigationOptions', screenProps.navigation.state.params);
};

When this screen gets navigated to, here's what I see in logs:

navigationOptions undefined
component did mount
navigationOptions {test: true}
navigationOptions undefined

Shouldn't it be:

navigationOptions undefined
component did mount
navigationOptions {test: true}

I've also noticed that output is correct when I wrap navigation.setParams in setTimeout:

useEffect(() => {
  setTimeout(() => {
      navigation.setParams({
        test: true,
      });
  }, 0);
}, []);

Invariant Violation: Maximum update depth exceeded when using setParams

const { setParams } = useNavigation();

useEffect(() => {
  setParams({ myParam: 'myValue' });
}, [setParams]);

causes Invariant Violation: Maximum update depth exceeded. And when using best practices according to eslint-plugin-react-hooks this dependency is automatically added. I suggest:

  • If setParams was immutable this wouldn't be a problem.
  • Not sure exactly how the plugin eslint-plugin-react-hooks works, but would of course be great if it wouldn't include something like setParams automatically. For setState this is the case - maybe using setState under the hood would make it smarter? Otherwise it's probably outside the scope of this package! :)

Provide stable navigation actions

function ReactComponent() {
  const { navigate } = useNavigation();
  useEffect(() => {
      if (someBoolean) {
          navigate(...)
      }
  },  [someBoolean,navigate])
}

The functions like navigate/goBack etc should be able to be used in hooks / dependency arrays.

We should rather make them stable so that they don't trigger effect re-execution on every navigate action, which is not the case currently (as reported by @cmmartin here: #3 (comment))

See also https://github.com/react-navigation/core/issues/71

The core does not provide stable action functions currently, and it may be complicated to do so and guarantee that as part of the core contract.

But we can provide stabilization in this package.

Error: Unable to resolve module `tslib`

Hello, I'm encountering following error during react-native run-android command.

error: bundling failed: Error: Unable to resolve module `tslib` from `PATH_TO_PROJECT/node_modules/react-navigation-hooks/dist/Hooks.js`: Module `tslib` does not exist in the Haste module map

This might be related to https://github.com/facebook/react-native/issues/4968
To resolve try the following:
  1. Clear watchman watches: `watchman watch-del-all`.
  2. Delete the `node_modules` folder: `rm -rf node_modules && npm install`.
  3. Reset Metro Bundler cache: `rm -rf /tmp/metro-bundler-cache-*` or `npm start -- --reset-cache`.
  4. Remove haste cache: `rm -rf /tmp/haste-map-react-native-packager-*`.
    at ModuleResolver.resolveDependency (PATH_TO_PROJECT/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:183:15)
    at ResolutionRequest.resolveDependency (PATH_TO_PROJECT/node_modules/metro/src/node-haste/DependencyGraph/ResolutionRequest.js:52:18)
    at DependencyGraph.resolveDependency (PATH_TO_PROJECT/node_modules/metro/src/node-haste/DependencyGraph.js:283:16)
    at Object.resolve (PATH_TO_PROJECT/node_modules/metro/src/lib/transformHelpers.js:264:42)
    at dependencies.map.result (PATH_TO_PROJECT/node_modules/metro/src/DeltaBundler/traverseDependencies.js:399:31)
    at Array.map (<anonymous>)
    at resolveDependencies (PATH_TO_PROJECT/node_modules/metro/src/DeltaBundler/traverseDependencies.js:396:18)
    at PATH_TO_PROJECT/node_modules/metro/src/DeltaBundler/traverseDependencies.js:269:33
    at Generator.next (<anonymous>)
    at asyncGeneratorStep (PATH_TO_PROJECT/node_modules/metro/src/DeltaBundler/traverseDependencies.js:87:24)

I've tried commands from error message and I've also tried to remove package completely and reinstall it but nothing seems to be working.

react-native: 0.60.3
react-navigation-hooks: 1.0.1

Thanks!

Proposal: Ability to pass params for tabBarOnPress defaultHandler function

I'd expect that underneath defaultHandler() function in navigationOptions > tabBarOnPress of bottom tab navigator, it runs navigate function (I may be wrong), but great addition would be to pass some params for those tabs; for example:

const MyNavigator = createBottomTabNavigator(
  {
    Home: {
      screen: HomeScreen,
      navigationOptions: () => ({
        tabBarOnPress: ({ navigation, defaultHandler }) => {
          defaultHandler({ foo: 'bar' });
        },
      }),
    },
  },
);

Types are missing and causing errors

Using react-navigation v4

Hook:
const navigation = useNavigation<any>();

Use hook:
navigation.popToTop();

Typescript error:
Property 'popToTop' does not exist on type 'NavigationScreenProp<any, NavigationParams>'.ts(2339)

useNavigationParam: useState-like interface?

Is it too late to suggest a change in the interface for useNavigationParam?

I'm working on some code and found myself using the navigation param as the only state for a scene of mine. The idea is that you pass in a value and a callback function as navigation params to a modal scene, which lets you edit said value and eventually accept it (which triggers the callback) or cancel (which just triggers goBack for now, but might as well call another callback if defined).

so I found myself writing something like

const value = navigation.getParam('value', '');
const setValue = (newValue) => { navigation.setParams({ value: newValue }); };

and using it much like I'd use useState.

So, thinking "this would be a useful abstraction on top of a useNavigation hook", I found this repo. I was thinking an interface like this for useNavigationParam might make sense, where you can either destruct out only the value, or get both the value and a setter function to update it. So I figured I might as well create an issue with this suggestion, and see what others think. :)

Include v5 patching for users converting from v4 to v5?

Would it be an idea to import useNavigation from `'@react-navigation/native';`` and use that if the user has react-navigation v5 installed? I'm in the process of upgrading from v4 to v5 and of course lots of my screens are broken.

It might be a silly idea?

Test on React-Native

I haven't actually run hooks yet on RN because its quite complicated right now. This was developed on the web.

Could somebody test this on a RN app and see if anything funky happens?

I can't define NavigationParams types with useNavigation

There is a way to define navigation params typing on useNavigation with typescript ?

  const navigation = useNavigation<{ params: { title: string } }>();
  const title = navigation.getParam("title"); // title is inferred as "any" not "string"...

This is not working useNavigation because of this (P default value/type) :

export interface NavigationScreenProp<S, P = NavigationParams> {
  state: S & { params?: P };
...

there is no access to optional second type on NavigationScreenProp...

useNavigation give the warning "can't perform a React state update on an unmounted component"

If I extract 'navigation' from props, everything is fine. However, if I decide to utilize useNavigation() which is part of react-navigation-hooks, I get this warning:

can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks...

Could be something is wrong with my useEffect hook?

import React, {useEffect} from 'react';
import {View, ActivityIndicator} from 'react-native';
import {isSignedIn} from './isSignedIn';
import {useNavigation} from 'react-navigation-hooks';

export const CustomAuthenticator: React.FC = () => {
  const [user, setUser] = React.useState(false);
  useEffect(() => {
    const res = async () => {
      const u = await isSignedIn();
      setUser(u);
    };
    return res;
  }, [user]);

  const {navigate} = useNavigation();
  return (
    <View>
      <ActivityIndicator>{navigate(user ? 'App' : 'Auth')}</ActivityIndicator>
    </View>
  );
};

useNavigation not working

function App(){
const navigation = useNavigation()
<Stack.Navigator
screenOptions={{
headerStyle: { backgroundColor: '#5F27CD' },
headerTintColor: '#fff',
headerBackTitleVisible: false,
headerLeftContainerStyle: { marginLeft: 17 },
}}
initialRouteName='Tabs'
>
<Stack.Screen
name='somename'
component={somepage}
options={{
title: 'sometitle',
headerLeft: () => (
<TouchableOpacity onPress={() => {navigation.navigate('somepage')}}>


),
}}
/>
</Stack.Navigator
}
Return me this error:

Error: Couldn't find a navigation object. Is your component inside a screen in a navigator?

This error is located at:
in AppRoutes (at routes.tsx:112)
in Routes (at App.tsx:149)
in EnsureSingleNavigator (at BaseNavigationContainer.tsx:268)
in ForwardRef(BaseNavigationContainer) (at NavigationContainer.tsx:39)
in ThemeProvider (at NavigationContainer.tsx:38)
in ForwardRef(NavigationContainer) (at App.tsx:147)
in BgTracking (at renderApplication.js:40)
in RCTView (at AppContainer.js:101)
in RCTView (at AppContainer.js:119)
in AppContainer (at renderApplication.js:39)

useNavigation
useNavigation.tsx:18:6
AppRoutes
routes.tsx:42:21
renderRoot
[native code]:0
runRootCallback
[native code]:0
forEach
[native code]:0
Refresh.performReactRefresh
setUpReactRefresh.js:43:6
setTimeout$argument_0
require.js:609:10
callFunctionReturnFlushedQueue
[native code]:0

Proposal: useNavigationEffect() hook

In addition to useNavigationEvents(handler), I propose two useNavigationEffect(handler)hooks, that look and feel similar to the official react useEffect(handler):

useNavigationEffectInsideTransition(() => {
    console.log('screen component did focus');
    return function cleanup() {
      console.log('screen component will blur');
    };
  });

and

useNavigationEffectOutsideTransition(() => {
    console.log('screen component will focus');
    return function cleanup() {
      console.log('screen component did blur');
    };
  });

As with the useEffect(handler) hook, the return of a cleanup function is optional.

To be honest the main problem is naming the two hooks to clarify if the effect is called inside the transitions or outside. Any alternative naming proposals are appreciated.
In my opinion these hooks would be much more intuitive, since people will be familiar with the useEffect(handler) hook.

Are there any common use cases that require the combination of
willFocus & willBlur or didFocus & didBlur
instead of
willFocus & didBlur or didFocus & willBlur?

What are your thoughts on this?

useNavigationEvents do not update listeners across re-renders

Hi,

I just want to warn that this implementation is problematic:

export function useNavigationEvents(handleEvt) {
  const navigation = useNavigation();
  useEffect(
    () => {
      const subsA = navigation.addListener('action', handleEvt);
      const subsWF = navigation.addListener('willFocus', handleEvt);
      const subsDF = navigation.addListener('didFocus', handleEvt);
      const subsWB = navigation.addListener('willBlur', handleEvt);
      const subsDB = navigation.addListener('didBlur', handleEvt);
      return () => {
        subsA.remove();
        subsWF.remove();
        subsDF.remove();
        subsWB.remove();
        subsDB.remove();
      };
    },
    // For TODO consideration: If the events are tied to the navigation object and the key
    // identifies the nav object, then we should probably pass [navigation.state.key] here, to
    // make sure react doesn't needlessly detach and re-attach this effect. In practice this
    // seems to cause troubles
    undefined
    // [navigation.state.key]
  );
}

The key is needed, otherwise the events will be removed/added on every update.
Unfortunately when you add a didFocus listener on a focused view, the listener will fire immediately after adding (async), which has lead to an infinite loop on this issue: react-navigation/react-navigation#5058

I suggest as a solution to:

  • store react-navigation listeners in a ref to make them stable
  • wire the user provided listeners to the stable listeners of the ref (so that user is still able to provide arrow functions/unstable listeners, and the latest provided version will be called, instead of the one provided on initial render)
  • only update react-navigation listeners on some specific conditions, like key change?

I can try to provide an implementation if you want

Recommended way to provide NavigationContext for testing

I'm shallow rendering a component that uses useNavigationParam and getting TypeError: Cannot read property 'getParam' of undefined. Is there a recommended way to provide NavigationContext for testing (I'm using Jest)? I used to just pass a fake navigation prop but that won't be passed to NavigationContext.

Getting error 'from' expected

Hi,

I've npm installed react-navigation-hooks and now as per the doc when I am importing using:

import * from 'react-navigation-hooks';

I am getting this error:

Screen Shot 2019-10-17 at 3 02 43 PM

Please help resolving this. Thank you.

setParams entity change when is called

This generates a loop when is used on useEffect

const { setParams } = useNavigation();

const { error, data, refetch } = Apollo.useQuery<GetCardsResponse>(GET_CARDS);

useEffect(() => {
    if (data) {
      setParams({ showTitle: data.cards.length > 0 });
    }
  }, [data, setParams]);

Uncaught Invariant Violation: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate.

This works:

useEffect(() => {
    if (data) {
      setParams({ showTitle: data.cards.length > 0 });
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [data]);

useNavigationParam: Set default

getParam provides a default as a second paramter to the function in case the requested param is null. useNavigationParam should provide that same behavior.

Reset Stack

How to reset the navigation stack, example: Login Screen for Home.

Hooks on the web - react-navigation is now directly imported

These hooks don't seem to work on the web. I'm trying to run this react-navigation web example but with latest versions. Between 1.0.0-alpha2 and 1.1.0 hooks now directly imports from react-navigation instead of relying on @react-navigation/core. So running the example with latest versions of hooks results in an error (below) even though it is listed only as a devDepdendency. If you then add react-navigation you'll of course end up with all the react-native stuff.

I'd like to use react-navigation and hooks on the web but it seems impossible. Our common code features many hooks that rely on this but I'm thinking react-router might be a safer choice for now.

Cannot find module 'react-navigation'
Require stack:
- /Users/aforty/Code/web-server-example/node_modules/react-navigation-hooks/dist/commonjs/Hooks.js
- /Users/aforty/Code/web-server-example/build/server.js
$ yarn add react-navigation
...
success Saved 5 new dependencies.
info Direct dependencies
└─ [email protected]
info All dependencies
├─ @react-navigation/[email protected]
├─ [email protected]
├─ [email protected]
├─ [email protected]
└─ [email protected]

_useNavigation.navigate

I'm using react-navigation-hooks in react native and i'm getting this error when i use the useNavigation example:

TypeError: undefined is not an object (evaluating '_useNavigation.navigate')

this is mi code:

import {useNavigation} from 'react-navigation-hooks';

export default function renderItmFlat(props) {

   const {navigate} = useNavigation();

   return(
           <TouchableOpacity
           //disabled={this.state.blockBtn?true:false}
               style={{flex: 1,
                   flexDirection: 'row',
                   paddingLeft: 15,
                   paddingVertical: 30,
                   borderRightColor: '#D7D7D7',
                   borderRightWidth: 0.5,
                   alignItems: 'center'}}
                   //onPress={onStartPress}
                   onPress={() => navigate('Store')}
                   >

could you help me please?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.