PLEASE NOTE that 'this' is not accessible from a static function: React Native : Access Component state inside a static function
I am trying to define a button in the screen's header that, when clicked, will affect rendering, and will be replaced with another icon.
It is an old app, still using react navigation 3.
I didn't know how to do the following things:
- modify the component's state from a function that is activated when the button is pressed
- modify the screen parameter from this function
What I managed to implement is the following lame and embarrassing way to do it:
- When the button is clicked, a static function is executed, which modfies a static variable
- periodic code is fired in componentDidMount that checks whether the static detailedDisplay variable has been modified. If it has been modified, this code sets a state variable that affects rendering. This periodic code also modifies the screen parameter which changes the icon in the header (because, as I wrote above, I also failed to set the parameter from the static function).
How can this be done in not-so-lame way?
Here is my code:
import React, { Component } from 'react';
import Icon from 'react-native-vector-icons/Octicons';
...
export default class Messages extends Component {
...
var detailedDisplay = false;
...
static navigationOptions = ({ navigation }) => {
return {
headerRight: //navigation.getParam('detailedDisplay', false) ?
detailedDisplay ?
<TouchableOpacity onPress={() => this.toggleDisplay(navigation)}>
<Icon name={"check-circle"} />
</TouchableOpacity> :
<TouchableOpacity onPress={() => this.toggleDisplay()}>
<Icon name={"comment"} />
</TouchableOpacity>,
};
};
static toggleDisplay(navigation) {
detailedDisplay = !detailedDisplay;
// the following statement gave the error "cannot read property
// 'setParams' of undefined", so I am setting it below.
// navigation.setParams({ detailedDisplay });
}
constructor(props) {
super(props);
this.state = {
detailedDisplay: false,
};
}
componentDidMount() {
setInterval(() => {
if (detailedDisplay !== this.state.detailedDisplay) {
this.props.navigation.setParams({ detailedDisplay });
this.setState({ detailedDisplay });
}
}, 500);
}
...
return (
<View>
{ this.state.detailedDisplay ?
{this.renderConcise()} :
{this.renderDetailed()}
}
</View>
);
}
renderDetailed() {
...
}
renderConcise() {
...
}
}