Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Params with DrawerNavigator #80

Closed
TomiHiltunen opened this issue Jan 29, 2017 · 32 comments
Closed

Params with DrawerNavigator #80

TomiHiltunen opened this issue Jan 29, 2017 · 32 comments

Comments

@TomiHiltunen
Copy link

TomiHiltunen commented Jan 29, 2017

DrawerNavigator doesn't seem to accept params as the second argument for props.navigation.navigate. I'm using custom drawer menu component. Problem is, that it does navigate to the view but the params are not there.

Here's how I'm using the navigation prop provided to the custom drawer menu component by DrawerNavigator:

const DrawerMenuView = (props) => {
    const {
        myLittleItems,
        navigation
    } = props;
    return (
        <View>
            {myLittleItems.map((myLittleItem) =>
                <MyCustomItemComponent
                    key={myLittleItem.uuid}
                    myLittleItem={myLittleItem}
                    onPress={() => {
                        navigation.navigate("MyItem", { "displayName": myLittleItem.displayName });
                    }} />
            )}
        </View>
    );
};

Is this by design or a bug?

ps. This is one of my attempts at getting dynamically created navigation items in the drawer menu.

@baderahmed
Copy link

I have the same problem !

@satya164
Copy link
Member

AFAIK TabRouter (which DrawerNavigation uses) doesn't support params currently.

cc @ericvicenti

@j-mendez
Copy link

This happens not just for the DrawerStack it happens when you try to pass data from into a new stack of any type. Current issue is that the params object is not being passed between stacks and we should easily be able to implement this into React-Navigation. @grabbou

@uxxman
Copy link

uxxman commented Feb 24, 2017

Any updates on this issue? Still facing it with "react-navigation": "^1.0.0-beta.5"

No params when using DrawerNavigator
screenshot from 2017-02-24 16-14-22

@grabbou
Copy link

grabbou commented Feb 24, 2017 via email

@hasLandon
Copy link

I just upgraded to beta 6 and as far as I can tell, the issue is still there

@coodoo
Copy link

coodoo commented Mar 9, 2017

Can confirm this is still happening in branch af787e5

@renanpupin
Copy link

Have same problem :(

@Kerumen
Copy link

Kerumen commented Mar 19, 2017

I have the same problem with a TabNavigator.

Did you had time to work on your fix @grabbou ?

@JulianKingman
Copy link

Can I help somehow?

@ericvicenti
Copy link
Contributor

@JulianKingman, yes! If you can write a PR for TabsRouter with a few test cases, it would be much appreciated!

@JulianKingman
Copy link

@grabbou @ericvicenti any hints on where to start, what your thoughts are on how to tackle this?

@mgtitimoli
Copy link

mgtitimoli commented Apr 6, 2017

Hi @JulianKingman,

TL;DR

Replace what it's here with:

if (didNavigate) {
  const childState = state.routes[activeTabIndex];
  let newChildState;

  const tabRouter = tabRouters[action.routeName];

  if (action.action) {
    newChildState = tabRouter
      ? tabRouter.getStateForAction(action.action, childState)
      : null;
  } else if (!tabRouter && action.params) {
    newChildState = {
      ...childState,
      params: {
        ...(childState.params || {}),
        ...action.params,
      },
    };
  }

  if (newChildState && newChildState !== childState) {
    const routes = [...state.routes];
    routes[activeTabIndex] = newChildState;
    return {
      ...state,
      routes,
      index: activeTabIndex,
    };
  }
}

(And now the explanation...)

In order to know where the issue is located, I did the following

  1. Found that the DrawerNavigator is composed by two TabRouters as you can see here, so this point me to the fact that the issue must be located within the TabRouter.
  2. After following a bit the code I found the place where NAVIGATE action is handled.
  3. I discovered that the only logic there is to handle the condition where a tab is also a router, and there is no code to create a new state by merging the action params with the destination route, and this is what the logic in the branch of if (!tabRouter && action.params) {...} from the code I wrote does.
  4. In case you wonder what code handles the case where the action has no params, well, it's a bit tricky, is this one (To improve this, I would extract each condition into an independent reducer (pure) function to clarify the intention of each section, but this is another story)

@ericvicenti
Copy link
Contributor

The contributors guide on the website will show you how to run tests. You can add a new test for TabsRouter which sets up two routers in a way similar to DrawerNavigator. Then you can write a test that verifies that getStateForAction will correctly merge params for a navigate action. Then once you have a failing test, you can change the router to fix it.

@JulianKingman
Copy link

Wow, thanks @mgtitimoli , that looks great.

@p30arena
Copy link

p30arena commented Jul 17, 2017

The Third Parameter passed gets undefined too, navigate('screen', {}, {type, routName, params})

I have a nested TabNavigator in a StackNavigator, I navigate from a DrawerNavigator to the StackNavigator one

DrawerNavigator -> navigate() -> StackNavigator -> TabNavigator

@quangduz
Copy link

quangduz commented Feb 2, 2018

const Drawer = DrawerNavigator({
  Home: { screen: HomeStack }, // HomeStack have default screen = **HomeScreen**
  NewNote: { screen: NewNoteStack }, // NewNoteStack have default screen = **NewNote1**
}

I wanna send props from HomeScreen to NewNote1 like this :
navigate('NewNote', {name: 'Job'})

Same issue, DrawerNavigator don't have state.params

So, bellow solutions can fixed it.
At Homescreen, i define new navigateAction like this:

const navigateAction = NavigationActions.navigate({
      routeName: 'NewNote',
      params: {name: 'Rob'},
      action: NavigationActions.navigate({ routeName: 'NewNote1', params: {name: 'Job'}})
    })

At button onpress event:

onPress={() => this.props.navigation.dispatch(navigateAction)

So, at NewNote1 screen, u will receive 2 navigation data, 1 for routeName: 'NewNote', 1 for routeName: 'NewNote1'.

DrawerNavigator don't accept params, so data for NewNote will dont have params (name: 'Rob'). But NewNote1 have params (name: 'Job').

As default, if u call params now, u will get error because it will call to NewNote params, not NewNote1.

Now, just filter data to get NewNote1 params. Params for NewNote will "undefined".
At NewNote1 screen:

componentDidMount() {
    let data = this.props.navigation.state.params;
    if(data) console.log(data.name); // => Job here
  }

Hope this can help someone. Sorry for bad english !

@radik
Copy link

radik commented Feb 23, 2018

@quangduz Thank you! You saved my time.

@montao
Copy link

montao commented Mar 18, 2018

It is not working. I tried everything. Nothing works. state.params is simply not there if you make an advanced app.

@ericvicenti
Copy link
Contributor

@montao, what is not working? What do you mean by advanced app? Can you show an example code snippet of what is not working for you? Please try the latest version of the library because we may have already fixed the problem. If you still see the problem, please file a new issue with all of these details.

@Harag
Copy link

Harag commented Mar 21, 2018

Note: I am new to react stuff (just been hacking it for couple of days) so I might have the cat by the **** but I spent so many hours reading different solutions to this I just had to comment.

@quangduz your solution looks like it works but it actually does two calls (NewNoteStack and NewNote1) which mucks up your stack (gives a you a premature back arrow)

Scenario 1:

initialRouteParams: {name: 'Job'} on NewNoteStack would do for hard coded parameters.

Scenario 2:
If your parameters should not be hard coded you can set intialRouteParams to a function using =>

Some suggested Scenario 2 use cases:

  • Because I have a contentComponent for my drawer a hack I used was to use a global let (let menuParams;) then in onpress of drawer items I set menuParams to what i needed for that menu item and then set initialRouteParams: {data: () => { return menuParams;}}
  • Fetch data from a rest api or something when called.
  • If React.Context worked this might be a good place to use it**???**
  • Wrap drawer and stacks in your own component, store parameters in properties and fetch values you need for initial parameters**???**

initialRoutParams can be accessed with props.navigation.state.params

@i2chris
Copy link

i2chris commented Mar 26, 2018

It really surpises me that react-navigation doesn't solve the problem of passing params from a stack navigator to a tabs navigator. Is this library not meant for creating complex apps? I can't imagine an application, except the absolute simplest, where this wouldn't be required most of the time.

@bernardakl
Copy link

Got same issue.
I will use redux state in replacement.

@maharjanaman
Copy link

maharjanaman commented May 29, 2018

any updates on this or workaround?

@donni106
Copy link

It really surpises me that react-navigation doesn't solve the problem of passing params from a stack navigator to a tabs navigator. Is this library not meant for creating complex apps? I can't imagine an application, except the absolute simplest, where this wouldn't be required most of the time.

@i2chris thx for writing this. I tried to get it working yesterday for quite a long time. In sample app without nested navigator it was working for the TabNavigator. But in the big app with nested stack not. Now I know that I do not have to try further.

👎

@Sasikiran234reddy
Copy link

Sasikiran234reddy commented Jun 28, 2018

can we pass data which we get from fetching API as drawer items in drawer navigation using react native.

Can u guys please help me....

@JulianKingman
Copy link

You’ll need to use the custom drawer contentComponent, see here: https://reactnavigation.org/docs/en/drawer-navigator.html

The easiest way will probably be to pass in a redux-connected component, then pass the fetched data into redux.

@peacelovesapples
Copy link

This is a nightmare.. is it really easier to use react navigation.

@sujitpk-perennial
Copy link

@quangduz I have tried your solution, now what I found is, componentDidMount called twice. First time params are undefined and second time got the result.
I am using react-navigation version "v1.0.0-beta.28".

I am not faced this issue for lower version. I upgraded the version to use popToTop function. But now end with this issue.

Can you suggest me solution?

@yadavjyo
Copy link

yadavjyo commented Oct 23, 2018

Hii,
How to navigate the page with some parameter from Drawer on on
Press event.
Please help me, I am a beginner .

@danielkolesnik

This comment was marked as abuse.

@react-navigation react-navigation locked and limited conversation to collaborators Nov 1, 2018
@brentvatne
Copy link
Member

if someone can post a new issue following the issue template i'm happy to look into this

joshuapinter pushed a commit to cntral/react-navigation that referenced this issue Sep 29, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests