4

I want add button in react-native header , the button is to mas and unmask password in the page, the problem on click when i change the state to change secureTextEntry value, the icon wont change will keep as the initial value; the function is working fine but the icon cant change

this.state.secureTextEntry ? "eye" : "eye-slash"

this is the main code

 class ChangePasswordScreen extends Component {
 constructor(props) {
     super(props);
     this.state = {
         newPassword: null,
         currentPassword: null,
         confirmPassword: null,
         errors: [],
         secureTextEntry: true

     };

     this.maskPassword = this.maskPassword.bind(this)
 }
 componentDidMount() {
     this.props.navigation.setParams({
         headerRight: ( < TouchableOpacity onPress = {
                 () => {
                     this.maskPassword();
                 }
             } > < Icon style = {
                 styles.eyeIcon
             }
             name = {
                 this.state.secureTextEntry ? "eye" : "eye-slash"
             }
             size = {
                 20
             }
             color = {
                 Colors.WHITE
             }
             /></TouchableOpacity > )
     })
 }
 static navigationOptions = ({
     navigation
 }) => {
     return {
         // headerTitle: <LogoTitle />,
         headerRight: navigation.state.params && navigation.state.params.headerRight,
     };
 };
 maskPassword = () => {
     this.setState({
         secureTextEntry: !this.state.secureTextEntry
     })

 }

}

3 Answers 3

16

Kinda late, might help someone nevertheless.

If you wish to add a button to the header of a screen, from the screen itself, not the App.js file and you are using a functional component, it goes like this:

import { useNavigation } from '@react-navigation/native'

export function Component() {
  const nav = useNavigation();
  useEffect(() => {
    nav.setOptions({
      headerRight: () => <Button />,
    });
  }, []);
}
Sign up to request clarification or add additional context in comments.

Comments

5

The problem is this.setState will not re-render header component . if you want to change header right then you have to call setParams again

Try this code in componentDidMount

componentDidMount() {
    this.props.navigation.setParams({
      headerRight: this.setHeaderRight(this.state.secureTextEntry)
    });
  }

Set function for header right

setHeaderRight = state => {
    //console.log("setHeaderRight", this.state.secureTextEntry);
    return (
      <TouchableOpacity
        onPress={() => {
          this.maskPassword();
        }}
      >
        <Icon
          style={styles.eyeIcon}
          name={state ? "eye" : "eye-slash"}
          size={20}
          color={Colors.WHITE}
        />
      </TouchableOpacity>
    );
  };

Set header right again when state set

maskPassword = () => {
    this.setState({
      secureTextEntry: !this.state.secureTextEntry
    });
    this.props.navigation.setParams({
      headerRight: this.setHeaderRight(!this.state.secureTextEntry)
    });
  };

Comments

1

You are setting a Component as a navigation param on Component mount and passing in a state value at the time the Component mounted.

This param never gets changed or updated again so the navigation header never gets re rendered.

A better way would be to pass the value of state directly as a navigation param and use that in the component that is used directly in the navigationOptions

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.