How can i hide and show stack navigator header in react-native? - react-native

How can I hide and then show header(stack navigator) by pressing a button ?
static navigationOptions = ({ navigation }) => {
return {
header : null
}
}
This code set header to null and hide header but i can't show it again.

You can try something like this
static navigationOptions = {
headerVisible: this.state.headerVisible,
};
And In the constructor Initialise the state by
this.state = {headerVisible: true}
And on the buttonPress You can change the state by
<Button onPress={() => this.setState({headerVisible: !this.state.headerVisible})} />

Do you could try this?
this.state={
header: null
}
static navigationOptions = {
header: this.state.header,
};
...
headerfunc(){
if(this.state.header === null){
this.setSate({
header: ""
});
}else{
this.setSate({
header: null
});
}
}
...
<Button onPress={() => this.headerfunc()} />

You can add a custom function to handle the header visibility.
Create a handler function in your screen component,
toggleHeader=()=>{
let currentVal = this.props.navigation.getParam('isHeaderVisible', true);
this.props.navigation.setParams({ isHeaderVisible: !currentVal });
}
Add this handler function to your Button
render(){
...
<Button onPress={() => this.toggleHeader()} />
...
}
Finally, add static navigationOptions in your screen,
static navigationOptions = ({navigation}) => {
let headerVisible = navigation.getParam('isHeaderVisible',true);
return {
headerVisible
}
}

Thanks for every one. headerVisible property doesn't work.
There is another property called headerMode, it just works in stack navigator's config and we can't change it in our screen :
const StackNaviagtor = createStackNavigator({
showScreen: {
screen: MyScreen
}
}, {
headerMode: 'none'
})
only header property in navigationOption work and we can change it in our screen
the solution is :
import { Header } from "react-navigation";
static navigationOptions = ({ navigation }) => {
return {
header: navigation.getParam('isFullscreen') ? null : (headerProps) => <Header {...headerProps} />
}
and then:
render() {
let isFullscreen = this.props.navigation.getParam('isFullscreen');
return (
<Button title='Full Screen' onPress={() => { this.props.navigation.setParams({ isFullscreen: !isFullscreen }) }} />
)

Related

How to change navigation header button style based on a state property in React Native using React Navigation?

I'm using react navigation in my RN app and trying to implement a form to submit some information. I'm using a button at the right header and want to style the button with different color to indicate whether the form is legal (e.g., white for a legal form and transparant for having important inputs left blank).
I use this.state.submitDisabled to indicate its legality and define the right header in componentDidMount() and pass the navigation param to the header to render in navigationOptions:
this.props.navigation.setParams({
headerRight: (
<MaterialHeaderButtons>
<Item title="submit" iconName="check"
color={this.state.submitDisabled ? colors.white_disabled : colors.white}
onPress={() => {
if (!this.state.submitDisabled) {
this.postEvent();
}
}}/>
</MaterialHeaderButtons>
),
});
However, the color change statement based on the value of this.state.submitDisabled did not work. I've checked its value, when this.state.submitDisabled is changed, the color of the button does not change. It seems that the color is determined when set as navigation params as above and will not change since then.
How can I achieve the effect of what I described?
when ever you change value of state also change navigation param too.see example
export class Example extends Component {
static navigationOptions = ({ navigation }) => {
const showModal = get(navigation, 'state.params.showModal');
return {
headerTitle: <Header
showModal={showModal}
backIcon />,
headerStyle: HeaderStyle,
headerLeft: null,
};
};
constructor(props) {
super(props);
this.state = {
showModal: false,
};
}
componentDidMount = () => {
this.props.navigation.setParams({
showModal: this.state.showModal,
});
}
handleModal=(value)=>{
this.setState({showModal:value});
this.props.navigation.setParams({
showModal: this.state.showModal,
});
}
render() {
return null;
}
}
In your implementation this.state.submitDisabled is not bound to the screen. Try the following:
static navigationOptions = ({ navigation }) => {
headerRight: (
<MaterialHeaderButtons>
<Item
title="submit"
iconName="check"
color={navigation.getParam('submitDisabled') ? colors.white_disabled : colors.white}
onPress={navigation.getParam('handlePress')}
/>
</MaterialHeaderButtons>
),
})
componentWillMount() {
this.props.navigation.setParams({
submitDisabled: this.state.submitDisabled,
handlePress: () => {
if (!this.state.submitDisabled) {
this.postEvent();
}
}
});
}

How to override navigation options in functional component?

To override navigation options using class components, it would be something like
export default class SomeClass extends Component {
static navigationOptions = ({ navigation }) => {
return {
title: navigation.getParam('headerTitle'),
}
}
componentDidMount() {
this.props.navigation.setParams({ headerTitle: someVariableThatComesFromExternalCall })
}
...
}
But how can I do this using functional component??
export default function SomeFunctionalCompoenent({ navigation }) {
// How and Where do I change the header title ?
useEffect(() => { navigation.setParams({ headerTitle: someVariableThatComesFromExternalCall })})
return (
...
)
}
You still need to define navigationOptions on your functional component. You do it like this:
export default function SomeFunctionalComponent({ navigation }) {
useEffect(() => {
navigation.setParams({
headerTitle: someVariableThatComesFromExternalCall
})
}, [])
}
SomeFunctionalComponent.navigationOptions = ({ navigation }) => {
return {
title: navigation.getParam('headerTitle'),
}
}
I've got a suspicion the accepted answer isn't for the currently latest version of react navigation (5), and it definitely doesn't work for this version, so here's a working example for #react-navigation/native v5.7.2 :
export default function SomeFunctionalComponent({ navigation }) {
useLayoutEffect(() => {
navigation.setOptions({
headerTitle: 'some other title',
})
}, [])
}
I've used this to access react context - to get the user's name and avatar so I can set a nice title bar for them. I've pasted in the code for this in case it helps anyone:
import React, { useContext, useLayoutEffect } from 'react';
import UserContext from '../context/UserContext';
const HomeScreen = ({ navigation }) => {
const userContext = useContext(UserContext);
useLayoutEffect(() => {
navigation.setOptions({
title : userContext.name,
headerLeft : () => (
<TouchableOpacity
onPress={() => {
navigation.openDrawer();
}}
>
<FastImage
style={styles.userPhoto}
resizeMode={FastImage.resizeMode.cover}
source={{ uri: userContext.avatar }}
/>
</TouchableOpacity>
),
});
}, [ userContext ]);
return (
// etc
);
}

how to a call static function (eg: static navigationOptions) from another function in react native

how can i call a static function (static navigationOptions) from any other function in react native?
It fails when using the this keyword, but is it possible to render static navigationOptions again by calling it?
If you want to change navigation options dynamically, try like this
static navigationOptions = ({ navigation }) => {
return {
title: navigation.getParam('otherParam', 'A Nested Details Screen'),
};
};
this.props.navigation.setParams({otherParam: 'Updated!'})
Another method
static navigationOptions = ({ navigation }) => {
const {state} = navigation;
return {
title: `${state.params.title}`,
};
};
ChangeThisTitle = (titleText) => {
const {setParams} = this.props.navigation;
setParams({ title: titleText })
}
call this.ChangeThisTitle('your title') wherever you want
They only way to achieve it is using navigation params. So set your headerleft property flag or value using setParams. That will solve the issue. Below mentioned code should be used in your class.
static navigationOptions = ({ navigation }) => {
const { params = {} } = navigation.state;
let buttonView =
<TouchableOpacity style={navItemStyle} activeOpacity={0.7} onPress={() => { params.logoutClick() }}>
<Text style={navItemTxt}> Logout</Text>
</TouchableOpacity >
return {
title: 'Home',
headerLeft: params.showHeaderLeft && buttonView
};
};
componentDidMount() {
this.props.navigation.setParams({
showHeaderLeft: this.props.headerFlag,
//headerFlag used above is your value and showHeaderLeft is the name of the param
});
}

How to call this.props from a static navigationOptions - react-navigation

I am trying to call a handlelogout() in onPress of button in the header of a stack navigator and then in the handlelogout() I am calling this.props.logout action which will call a navigation reducer to reset to login screen.....but this.props.logout doesnt call an action....nothing happens
static navigationOptions = ({ navigation }) => {
const { params } = navigation.state;
console.log("navigation", navigation);
return {
title: "Profile List",
gesturesEnabled: false,
headerLeft: null,
headerRight: <Button title={"Logout"} onPress={() => params.handlelogout && params.handlelogout({ state: navigation.state })} />
}
};
this is my handlelogout function
handlelogout(state) {
console.log("in handlelogout", this.props.logout, state);
this.props.logout;
}
i am attaching the log i printed in the console
here I am binding the logout to mapdispatchprops
function mapDispatchToProps(dispatch) {
return bindActionCreators(ReduxActions, dispatch);
}
You can try to put the button inside another element then handle your logout from that element/class.
import ButtonForLogout from './test/buttonforlogout';
...
static navigationOptions = ({ navigation }) => {
const { params } = navigation.state;
console.log("navigation", navigation);
return {
title: "Profile List",
gesturesEnabled: false,
headerLeft: null,
headerRight: <ButtonForLogout />
}
};
buttonforlogout.js
import React, { Component } from 'react';
import { View, Button } from 'react-native';
import { connect } from 'react-redux';
import { ReduxActions } from './youractions';
class ButtonForLogout extends Component {
render(){
return(
<View>
<Button title={"Logout"} onPress={this.props.logout} />
</View>
);
}
}
const mapStateToProps = state => ({});
export default connect(mapStateToProps, ReduxActions)(ButtonForLogout);
Something like that.

React native navigation class function in header

I've got a problem with react native navigation and nested navigators.
Basically, the nested navigators (tab in a page) work pretty well. But when i add a button in the header with the _saveDetails function, it throw me an undefined function if i'm in the Players tab, and it works well when i'm on the Teams tab
Does anyone have an idea of what am i doing wrong? Thanks.
class HomeScreen extends React.Component {
static navigationOptions = ({ navigation }) => {
const { params = {} } = navigation.state;
return {
headerRight: <Button title="Save" onPress={() =>
params.handleSave()} />
};
};
_saveDetails() {
console.log('clicked save');
}
componentDidMount() {
this.props.navigation.setParams({ handleSave: this._saveDetails });
}
render() {
return (
<View />
);
}
}
const MainScreenNavigator = TabNavigator({
Players: { screen: HomeScreen},
Teams: { screen: HomeScreen},
});
const SimpleApp = StackNavigator({
Home: { screen: MainScreenNavigator },
Player: { screen: PlayerPage },
});
Please try this one and let me know if you fetch any other problem. Just convert your code according to below code.
static navigationOptions = {
header: (navigation, header) => ({
...header,
right: (
navigation.navigate('Settings')}>
Settings
)
})
}
Thanks
Just change your code become like this
class HomeScreen extends React.Component {
static navigationOptions = ({ navigation }) => {
// const { params = {} } = navigation.state; //delete this
return {
headerRight: <Button title="Save" onPress={() =>
navigation.state.params.handleSave()} /> // add navigation.state
};
};
.....