Search code examples
reactjsreact-nativesimplemodalonpressreact-native-modal

Why do I have to click two times to open the <Modal /> when I return from a page?


I made a button type to open the modal on the Home page, the modal is coming fine and closing fine when click on the overlay, the problem is when I got some page with the list inside<Modal /> component and when I come back to the Home page and then if I click on that button to open the it doesn't open on first click yet. I have to click two times to open it. What is the issue here? I can't understand.

Here is my code:

//Home.js
const modalData = [
  { key: "Add Dealer", navigateTo: "AddDealer" },
  { key: "Add Franchise", navigateTo: "AddFranchise" },
  { key: "New Lead", navigateTo: "AddNewLeads" },
];

export default function Home() {
  const [modalVisible, setModalVisible] = useState(false);

  const renderPopList = ({ item, index }) => {
    const lastItem = index === modalData.length - 1;
    return (
      <TouchableOpacity onPress={() => navigation.navigate(item.navigateTo)}>
        <Text style={[styles.links, lastItem && styles.lastLink]}>
          {item.key}
        </Text>
      </TouchableOpacity>
    );
  };

  const toggleModal = () => {
    setModalVisible(!modalVisible);
  };
  return (
    <>
      <Modal
        animationType="slide"
        transparent={true}
        visible={modalVisible}
        onRequestClose={toggleModal}
        onTouchStart={toggleModal}
        style={styles.modalWrapper}
      >
        <TouchableWithoutFeedback onPress={toggleModal}>
          <View
            style={{ flex: 1, backgroundColor: "rgba(0,0,0,0.1)" }}
            onPress={toggleModal}
          ></View>
        </TouchableWithoutFeedback>
        <FlatList
          data={modalData}
          renderItem={renderPopList}
          onPress={toggleModal}
          style={[styles.modal]}
        />
      </Modal>
      //Button Here
      <View style={styles.bottomBtnWrap}>
        <TouchableOpacity style={styles.addBtn} onPress={toggleModal}>
          <FontAwesome color="#fff" name="plus" size={30} />
        </TouchableOpacity>
      </View>
    </>
  );
}

Solution

  • you can use this code for it

    //Home.js
    const modalData = [
      { key: "Add Dealer", navigateTo: "AddDealer" },
      { key: "Add Franchise", navigateTo: "AddFranchise" },
      { key: "New Lead", navigateTo: "AddNewLeads" },
    ];
    
    export default function Home({ navigation }) {
      const [modalVisible, setModalVisible] = useState(false);
    
      useEffect(() => {
        const unsubscribe = navigation.addListener("blur", () => {
          setModalVisible(false);
        });
    
        return unsubscribe;
      }, [navigation]);
    
      const renderPopList = ({ item, index }) => {
        const lastItem = index === modalData.length - 1;
        return (
          <TouchableOpacity onPress={() => navigation.navigate(item.navigateTo)}>
            <Text style={[styles.links, lastItem && styles.lastLink]}>
              {item.key}
            </Text>
          </TouchableOpacity>
        );
      };
    
      const toggleModal = () => {
        setModalVisible(!modalVisible);
      };
    
      return (
        <Modal
          animationType="slide"
          transparent={true}
          visible={modalVisible}
          onRequestClose={toggleModal}
          onTouchStart={toggleModal}
          style={styles.modalWrapper}
        >
          <TouchableWithoutFeedback onPress={toggleModal}>
            <View
              style={{ flex: 1, backgroundColor: "rgba(0,0,0,0.1)" }}
              onPress={toggleModal}
            ></View>
          </TouchableWithoutFeedback>
          <FlatList
            data={modalData}
            renderItem={renderPopList}
            onPress={toggleModal}
            style={[styles.modal]}
          />
        </Modal>
        //Button Here
        <View style={styles.bottomBtnWrap}>
          <TouchableOpacity style={styles.addBtn} onPress={toggleModal}>
            <FontAwesome color="#fff" name="plus" size={30} />
          </TouchableOpacity>
        </View>
      );
    }