AlexanderTGreat
AlexanderTGreat

Reputation: 55

React Native searchbar with react-navigation

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>
        )
    }
}; 

enter image description here

enter image description here

Upvotes: 1

Views: 9932

Answers (2)

AlexanderTGreat
AlexanderTGreat

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

Zem Zem
Zem Zem

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

Related Questions