Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass the value of useState to BackHandler.addEventListener

Tags:

react-native

I'm using React Hooks and when I create an event listener for android back press handler, the state inside the callback function handler is empty!

In class components it works fine!

'use strict';

import React, { useState, useEffect } from 'react';
import { BackHandler } from 'react-native';
import TextInput from '../../../../components/TextInput';

export default function Foo() {
  const [comment, setComment] = useState('');

  useEffect(() => {
    const handler = BackHandler.addEventListener(
      'hardwareBackPress',
      handleValidateClose
    );
    return () => handler.remove();
  }, []);

  const handleValidateClose = () => {
    /* Here is empty */
    console.log(comment);
  };

  return <TextInput onChangeText={setComment} value={comment} />;
}

The value should be the useState changed

like image 908
Mauricio Carlezzo Avatar asked Dec 06 '22 09:12

Mauricio Carlezzo


1 Answers

handleValidateClose should be on your dependency array.

You can use your function outside the useEffect but should use with useCallback.

 const handleValidateClose = useCallback(() => {
    console.log(comment);
    return true;
  }, [comment]);

  useEffect(() => {
    const handler = BackHandler.addEventListener(
      'hardwareBackPress',
      handleValidateClose,
    );

    return () => handler.remove();
  }, [handleValidateClose]);

You can also move the definition to inside useEffect, and add a comment as a dependency.

useEffect(() => {
    const handleValidateClose = () => {
      console.log(comment);
      return true;
    };

    const handler = BackHandler.addEventListener(
      'hardwareBackPress',
      handleValidateClose,
    );

    return () => handler.remove();
  }, [comment]);

To clean things up, create a useBackHandler.

export default function useBackHandler(handler) {
  useEffect(() => {
    BackHandler.addEventListener('hardwareBackPress', handler);

    return () => {
      BackHandler.removeEventListener('hardwareBackPress', handler);
    };
  });
}

And use it like this:

const handleValidateClose = () => {
    console.log(comment);
    return true;
  };

  useBackHandler(handleValidateClose);

Please config your project to use the eslint-plugin-react-hooks. That's a common pitfalls that the plugin would help you with.

like image 96
Pedro Henrique Avatar answered Jun 27 '23 15:06

Pedro Henrique