How to pass navigation via a method? - react-native

I'm new to react-navigation and I would like to pass "navigation" as a props so I could use it. Because when I tried to use it in the other compo It is throwing an error message saying "undefined this.props.navigation etc.."
So here is what I would like to do
goto={()=>this.props.navigation.navigate('ChatBox', {
avatarUrl: matches.avatarUrl,
name: matches.name,
navigation: this.props.navigation
})}
As you can see I'm passing navigation via props to my compo named 'ChatBox'. But the problem is that my 'ChatBox' compo is not receiving the navigation. Could someone help me ? thanks

There are a few concepts I think you missed out on.
Every component mentioned in the stack navigator class gets a navigation object in its scope. You can access the same by using this.props.navigation()
If you need to pass navigation object to any other screen not mentioned in the stack navigator class, you'll be required to provide it as props, such as <Chatbox navigation={this.props.navigation} />
In your case, your navigation object is correctly being sent, just that you are fetching it wrongly in your Chatbox component. Your navigation as a prop is encapsulated in the navigation object itself ( .i.e. its present in this.props.navigation.state.params.navigation ) and since you haven't mentioned Chatbox component in your stack navigator class, you can't reference the navigation object as it is currently out of scope.
So,
You can replace a component by rendering the <Chatbox/> component and provide it the props ( as mentioned in point 2 above ) instead of navigating to the component.
If you need to navigate to the component, you'll be required to define the Chatbox screen in the stack navigator class and then you can use your navigation object.

Related

How to pass params in React Native Navigation for the goBack() function

I know this is a stupid question.
I have a component lets call it Component that is used in several screens for Example Screen1,Screen2,...
And in the Component I am navigating to a new Screen when the user click a button, lets call it ImagePicker.
my Question is how do I go back and pass a parameter( in this case image data) and get it back in the Component
I tried using navigation.goBack({img: image}) but that didn't work. I also can't use navigation.navigate('Screen') since my functions are in the Component component.
So what is the best solution for my problem ?
We cannot pass any params to the goBack method.
If we have to do so then, we can use the navigate method to navigate to the back screen, and using this method we can pass the params to the previous screen.
For ex.
navigation.navigate('PrevScreenName', {key: value})
Check out the official docs for the react-navigation.
React Navigation
If I understand your problem well, just do
navigation.navigate('Screen', {img: image})
instead of navigation.goBack({img: image}) and it should work
In the component code, I would pass along a callback function to the image picker screen
handleImageData = (data) =>
{
// do whatever
}
...
navigation.navigate('ImagePickerScreen',{mycallback:this.handleImageData});
and then in the screen code just call it like
this.props.route.params.mycallback(data);
navigation.goBack();

How to call a method from different component in React Native

I have a snack setup:
https://snack.expo.io/#sj458147/view-not-scrolling
when you click show modal -> Click next button the View horizontally scrolls (animated), which then displays an image carousel. Now when you click an image, the View should horizontally scroll again but I get the error undefined is not an object. The error lies within the file:
SliderEntry.js
select = () => {
this.MyScrollView.current.moveToPage(3);
};
any help resolving the issue would be appreciated. Thanks in advance
You have MyScrollView ref in ShowModal. There are 2 ways:
Not recommend: Pass MyScrollView ref as props to Slider, then pass to SliderEntry
Recommend: create a callback as props in SliderEntry. Callback to Slider, then callback to ShowModal
Pass your function in props to other components and then access these functions from your another component.
You can find the answer here
React : Pass function to child component

How to deal with state during a screen transition using react native and react navigation

I am getting an object undefined exception during a transition from one screen to another. I have a pretty good idea what is happening, I am just not sure if there is a clean way of handling it without just checking for undefined everywhere.
Here is my scenario:
Source screen references a user object in a Redux store
Navigation is initiated from the source screen to the destination screen.
The destination screen componentDidMount() is called where I clear the user object from the Redux store.
The source screen render() gets called again and the undefined error occurs because I cleared user from the store.
I am assuming that the source and destination screens have some overlap due to the transition. I have tried adding listeners with no luck. I can only get listener handlers to fire for type = action,
I am probably making this more complicated than it is, but I would like to find out if there is a standard way of dealing with this or if I am going about it in a completely wrong way.
Also, my react-navigation is integrated with Redux as per the instructions on React Navigation's website and the Redux React Navigation sample code.
Here is the basic code.
Screen 1
componentDidMount() {
// This is a Redux action that sets an object called user to null
clearUser();
{
Screen 2
render() {
return (
// Other code here
// user is null here because render gets called after Screen1#componentDidMount() gets called
<Text>{user.firstName + ' ' + user.lastName}</Text>
<TouchableOpacity
onPress={() => navigation.dispatch({ type:'NAV_SCREEN_1' })}
>
// button code here
</TouchableOpacity>
// Other code here
)
}
The type of error is "TypeError: Cannot read property 'firstName' of null"
I understand the error and why I am getting it. The user object has been set to null by my Redux action in componentDidMount() of Screen 1 and then Redux causes render of Screen 2 to get called which is referencing a user object which is null.
My question is, is there a special way to accommodate this behavior without having to check if the user object is null every place I need to use it ? Should I call clearUser() somewhere else ?
For the newest version of react-navigation, you can use either addListener, withNavigationFocus or isFocused to detect transition state of the screens.
Another unofficial way is to catch action type NavigationActions.COMPLETE_TRANSITION, in case of using middleware like redux-saga.
As an alternative, you can simply make your Redux-connected screen handle undefined or null state. I had a similar problem and I ended up rendering a loader instead of the screen content when user state is undefined. When I log out, the screen shows a loader for a fraction of a second, then the app navigates away.

What is considered a screen by react-navigation?

What is considered a screen by react-navigation?
Is it any entry in the RouteConfigs (i.e. StackNavigator)?
Does it also need to be an ES6 class?
I am trying to access the this.props.navigation but props is undefined and I suspect that it is because my component is a stateless functional component.
If I turn it into a class the props are there.
Is there a way to work with stateless functional components and navigation?
When you work with stateless components, you can’t access the props using this.props, as stateless means just a simple function (rather than a class instance) i.e. without this. So, you can access props using the function arguments instead. See the following two examples:
const StatelessComponent = props => (
<div>{props.label}</div>
);
or alternatively:
const StatelessComponent = ({label , anotherProp}) => (
<div>{label}</div>
);
So in your case, just simply access props.navigation.

Using Navigator in React Native

I am using the Navigator component for React Native and so far so good, but ...
I can't seem to push() to the navigator from within the same component. Here is an example:
updateNav(){
navigator.push({page: 'newPage'});
}
render(){
return (
<Navigator initialRoute={{page: INITIAL_TAB}} />
)
}
When I call
updateNav()
I get an error saying that 'navigator' is undefined.
Also, I can pass the navigator to children and update the Navigator from the children via 'props' with no problem. But I have a case where I need to update the push to the Navigator from within the same component that has the Navigator component.
The navigator is a property that you pass down to your scenes, so it won't be available in the same component you're rendering Navigator. I ran into this issue too and just moved up the Navigator to a higher component and made the current one the initial route.
I think navigator should be on your props
this.props.navigator