I'm trying to build a very simple Todo application in React Native. It's composed of two views : one with a list of tasks, one with an input field (to add a new one). Navigation is assured by a NavigatorIOS
and buttons on it (which would have been UIBarButtonItem
with UIKit).
On the list view, there is a Add right button on Navigator, on the view with the text field, there the back button on the left and a Done one on the right. When clicking on done, it should add a new task with content of text field.
Problem is, buttons and their actions are defined when creating the NavigatorIOS
component, and I don't find a way to attach a method defined in another component as a button action.
As an example, here is my NavigatorIOS
class TodoList extends Component {
render() {
return (
<NavigatorIOS
ref="nav"
style={styles.navbar}
initialRoute={{
component: ItemList,
title: 'Todo list',
rightButtonTitle: 'Add',
onRightButtonPress: () => {
this.refs.nav.push({
title: 'Add a new task',
component: AddTodo,
rightButtonTitle: 'Done',
onRightButtonPress: () => {
console.log('done !');
}
});
}
}}
/>
);
}
}
I don't put here my two other components ItemList
and AddTodo
as there is nothing interesting on it.
What I need is a way to make components communicate (like in delegation pattern) with the navigation component.
Perhaps it's not possible, or I am totally wrong on the paradigm used with React Native, so feel free to comment if something is not clear on my question.
Edit 05/26
Actually, Facebook team is aware that something is missing to handle that use case with NavigatorIOS
component.
From Eric Vicenti (posted on February 3 2015) on an issue on GitHub that exactly covers my question.
Currently the best way to do that is to create an
EventEmitter
in the owner of theNavigatorIOS
, then you can pass it down to children usingroute.passProps
. The child can mix inSubscribable.Mixin
and then incomponentDidMount
, you canthis.addListenerOn(this.props.events, 'myRightBtnEvent', this._handleRightBtnPress);
It is clear that this API needs improvement. We are actively working the routing API in Relay, and hopefully react-router, but we want NavigatorIOS to be usable independently. Maybe we should add an event emitter inside the navigator object, so child components can subscribe to various navigator activity:
this.addListenerOn(this.props.navigator.events, 'rightButtonPress', this._handleRightBtnPress);
A. In initial component
this.props.navigator.push({
title: 'title',
component: MyComponent,
rightButtonTitle: 'rightButton',
passProps: {
ref: (component) => {this.pushedComponent = component},
},
onRightButtonPress: () => {
// call func
this.pushedComponent && this.pushedComponent.myFunc();
},
});
B. In pushed component
replace onRightButtonPress func in pushed component.
componentDidMount: function() {
// get current route
var route = this.props.navigator.navigationContext.currentRoute;
// update onRightButtonPress func
route.onRightButtonPress = () => {
// call func in pushed component
this.myFunc();
};
// component will not rerender
this.props.navigator.replace(route);
},
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