What I've been trying is to pass a callback into a screen.
Here is an excerpt of my experimentation...
export default class Test extends React.Component {
constructor(props) {
super(props);
};
handleOnPress(data){
//How do we pass this callback to "Home" or "Sub"?
}
render() {
const Navigator = StackNavigator({
Home: {screen: Home},
Sub: {screen: Sub}
});
let data = {blah:"blah blah"};
return (<Navigator screenProps={data} />);
}
}
In this example, I can get this.props.screenProps.blah
in both Home
and Sub
.
I assumed that being able to pass a prop would mean being able to pass a call back too, but I feel like I wasn't right.
Has anyone encountered this issue?
Any advice will be appreciated.
React Navigation related packages include @react-navigation/drawer , @react-navigation/stack , @react-navigation/bottom-tabs and @react-navigation/material-top-tabs use react-native-gesture-handler and react-native-reanimated for smooth gestures and animations.
The React useCallback Hook returns a memoized callback function. Think of memoization as caching a value so that it does not need to be recalculated. This allows us to isolate resource intensive functions so that they will not automatically run on every render.
If you just want to pass a callback to a child, you could specify in your render as a prop too:
<Navigator callback={this.handleOnPress} {/*And any other props you want to pass*/} />
And then in your Home
or Sub
class to trigger the callback as you probably expect
class Home extends React.Component {
//...
somefunction = () => {
this.props.callback();
}
}
This is what I am using in my code right now.
Though if you want to pass it to only either one of Home
or Sub
, this here is probably your answer: https://github.com/react-community/react-navigation/issues/935
const mapNavigationStateParamsToProps = (SomeComponent) => {
return class extends Component {
static navigationOptions = SomeComponent.navigationOptions; // better use hoist-non-react-statics
render() {
const {navigation: {state: {params}}} = this.props
return <SomeComponent {...params} {...this.props} />
}
}
}
EDIT: In my case, my handler was an arrow function written like so:
handleOnPress = (data) => {
//Do something here
}
It is so that I do not have to deal with .bind()
s
FINAL SOLUTION by OP:
Looks like StackNavigator
requires props to be passed as screenProps
, so, render function becomes:
render() {
const Navigator = StackNavigator({
Home: {screen: Home},
Sub: {screen: Sub}
});
let props = {
data: "data",
handleOnPress: () => this.handleOnPress()
};
return (<Navigator screenProps={props} />);
}
passing a callback through react native navigation params is not recommended, this may cause the state to freeze (to not to update correctly). The better solution here would be using an EventEmitter, so the callback stays in the Screen1 and is called whenever the Screen2 emits an event.
Screen 1 code :
import DeviceEventEmitter from "react-native"
DeviceEventEmitter.addListener("event.testEvent", (eventData) =>
callbackYouWantedToPass(eventData)));
Screen 2 code:
import DeviceEventEmitter from "react-native"
DeviceEventEmitter.emit("event.testEvent", {eventData});
useEffect(() => {
return () => {
DeviceEventEmitter.removeAllListeners("event.mapMarkerSelected")
};
}, []);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With