Reputation: 55
I would like to add a searchbar in my header. I am using react-navigation, and want to create an effect like in the below 2 pictures. When you press the search icon, the hamburger icon becomes a arrow-back icon, the header title becomes a search field. I have tried to accomplish this with the navigationOptions but the problem is that it is static and it cannot be updated when an action happens on the header itself. So for experimenting what I want to accomplish is that when the search icon is pressed, the hamburger icon becomes a arrow-back icon. Thank you!
var search = false;
const menuButton = navData => (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
title="Menu"
iconName="ios-menu"
onPress={() => {
navData.navigation.toggleDrawer();
}}
/>
</HeaderButtons>
);
const goBackButton = navData => (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
title="Menu"
iconName="ios-arrow-back"
onPress={() => {
search=false
}}
/>
</HeaderButtons>
);
MyScreen.navigationOptions = navData => {
return {
headerTitle: 'My title',
headerLeft: search ? goBackButton : menuButton(navData),
headerRight: (
<BorderlessButton
onPress={() => search=true}
style={{ marginRight: 15 }}>
<Ionicons
name="md-search"
size={Platform.OS === 'ios' ? 22 : 25}
/>
</BorderlessButton>
)
}
};
Upvotes: 1
Views: 9932
Reputation: 55
I have fixed it by passing information to my navigationOptions with setParams and getParam. The only problem I faced was in infinite loop which I could solve with the proper use of useEffect and useCallback.
const MyScreen = props => {
const dispatch = useDispatch();
var search = useSelector(state => state.verbs.search);
useEffect(() => {
props.navigation.setParams({search: search});
}, [search]);
const toggleSearchHandler = useCallback(() => {
dispatch(toggleSearch());
}, [dispatch]);
useEffect(() => {
props.navigation.setParams({toggleSearch: toggleSearchHandler});
}, [toggleSearchHandler]);
return (<View> ...
</View>
);
};
MyScreen.navigationOptions = navData => {
const toggleSearch = navData.navigation.getParam('toggleSearch')
return {
headerTitle: 'Verbs',
headerLeft: navData.navigation.getParam('search') ? gobackButton : menuButton(navData),
headerRight: (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
title="Menu"
iconName="ios-star"
onPress={toggleSearch}
/>
</HeaderButtons>
)
}
};
Upvotes: 0
Reputation: 139
try use state bro !
constructor(props) {
super(props);
this.state = {
search:false
}
}
const menuButton = navData => (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
title="Menu"
iconName="ios-menu"
onPress={() => {
navData.navigation.toggleDrawer();
}}
/>
</HeaderButtons>
);
const goBackButton = navData => (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
title="Menu"
iconName="ios-arrow-back"
onPress={() => {this.setState({search:false})}}
/>
</HeaderButtons>
);
MyScreen.navigationOptions = navData => {
return {
headerTitle: 'My title',
headerLeft: this.state.search ? goBackButton : menuButton(navData),
headerRight: (
<BorderlessButton
onPress={() => {this.setState({search:true})}}
style={{ marginRight: 15 }}>
<Ionicons
name="md-search"
size={Platform.OS === 'ios' ? 22 : 25}
/>
</BorderlessButton>
)
}
};
Upvotes: 0