react-nativereact-hooksreact-native-modal

When I try to run the react-native modal from the other page, I can run it by clicking twice


Since I had to use modal in most places in the application, I wanted to gather the main structure of all of them at a certain point..When I try to do like this it works first click but If I want to call again I have to press these bell icon twice . I looked at many solutions but they didn't work at all.I looked at many solutions but they didn't work at all. Here is my modal.js code .

import { View, Text, TouchableOpacity } from 'react-native';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import React, { useState, useEffect } from 'react';
import Modal from 'react-native-modal';

export default function CustomModal({ modalVisible, children }) {
    const [isVisible, setIsVisible] = useState(modalVisible);
  
    useEffect(() => {
      setIsVisible(modalVisible);
    }, [modalVisible]);
  
    const closeModal = () => {
      setIsVisible(false);
    };

  return (
    <Modal
      isVisible={isVisible}
      onSwipeComplete={closeModal}
      style={{ justifyContent: 'flex-end', margin: 0, alignItems: 'center' }}
      useNativeDriver={true}
      backdropTransitionOutTiming={0}
      hideModalContentWhileAnimating
      onBackButtonPress={closeModal}
      onBackdropPress={closeModal}>
      <View
        style={{
          backgroundColor: 'white',
          padding: 0,
          height: 'auto',
          borderTopRightRadius: 12,
          borderTopLeftRadius: 12,
          width: '100%',
        }}>
        
        <View
          style={{
            backgroundColor: '#f5f6f6',
            justifyContent: 'space-between',
            flexDirection: 'row',
            alignItems: 'center',
            padding: 16,
            borderTopRightRadius: 12,
            borderTopLeftRadius: 12,
          }}>
          <Text style={{ color: 'black', fontSize: 16 }}>Hello</Text>
          <TouchableOpacity onPress={closeModal}>
            <Icon color="black" name="close" size={16} />
          </TouchableOpacity>
        </View>

        {children}
        <View style={{ padding: 20, alignItems: 'center' }}>{children}</View>
      </View>
    </Modal>
  );
}

//And I call these codes in my dashboard 
const [visible , setVisible] = useState(false);
<Modal modalVisible={visible} />
<IconButton icon='bell' iconColor='#EA580C' size={30} onPress={() => setVisible(prevVisible => !prevVisible)} />

When I try to do like this it works first click but If I want to call again I have to press these bell icon twice. I looked at many solutions but they didn't work at all.I looked at many solutions but they didn't work at all.


Solution

  • Remove the state from CustomModal and control visibility from the parent. Also use true when opening modal not negation operator. Something like this:

    const CustomModal = ({ show, onClose, children }) => {
      return (
        <Modal
          visible={show}
          onRequestClose={() => {
            onClose();
          }}>
    ...
        </Modal>
      );
    };
    
    const [visible, setVisible] = useState(false);
    
    <CustomModal show={visible} onClose={() => setVisible(false)}>
      ...
    </CustomModal>
    <Button title="Open" onPress={() => setVisible(true)} />