skip to Main Content

How can I close my Modal which is inside another custom component?
My modal is in another component. I have a problem passing a state to the parent component. You can see the parent and child component below.

Parent Component:

const ViewNote = ({route, navigation}) => {
  const [visible, setVisible] = useState(false);

  function visibility(cases) {
    setVisible(cases);
    console.log(cases);
  }

  return (
    <View style={styles.noteContainer}>

        {/* MODAL */}
        <FancyAlert visible={visible} />
        <View style={styles.deleteContainer}>
          <Pressable android_ripple={{color: '#d9d9d9'}} onPress={() =>  setVisible(true)}>
            <MaterialIcons style={styles.icon} name='delete' size={40}/>
          </Pressable>
        </View>

    </View>
  )
}

export default ViewNote

Child Component:

const FancyAlert = ({visible}) => {
  const [showAlert, setShowAlert] = useState(false);

  return (
    <Modal transparent visible={visible}>
      <View style={styles.modalContainer}>
        <View style={styles.dialogContainer}>
          <Text style={[styles.text, {fontSize: 16}]}>Are you sure you want to delete this note?</Text>

          <View style={styles.buttonContainer}>
            <Pressable style={styles.cancel} android_ripple={{color: '#d9d9d9'}} onPress={() => setVisible(false)}>
              <Text style={[styles.text, {fontFamily: 'SofiaProBold'}]}>Cancel</Text>
            </Pressable>
            
          </View>
        </View>
      </View>
    </Modal>
  )
}

export default FancyAlert

3

Answers


  1. Move state to parent component. And pass onClose function.

    const ViewNote = ({route, navigation}) => {
      const [visible, setVisible] = useState(false);
    
      function visibility(cases) {
        setVisible(cases);
        console.log(cases);
      }
    
      return (
        <View style={styles.noteContainer}>
    
            {/* MODAL */}
            <FancyAlert visible={visible} onClose={() => setVisible(false)} />
            <View style={styles.deleteContainer}>
              <Pressable android_ripple={{color: '#d9d9d9'}} onPress={() =>  setVisible(true)}>
                <MaterialIcons style={styles.icon} name='delete' size={40}/>
              </Pressable>
            </View>
    
        </View>
      )
    }
    
    export default ViewNote
    
    const FancyAlert = ({visible, onClose}) => {
     
      return (
        <Modal transparent visible={visible} onClose={onClose}>
          <View style={styles.modalContainer}>
            <View style={styles.dialogContainer}>
              <Text style={[styles.text, {fontSize: 16}]}>Are you sure you want to delete this note?</Text>
    
              <View style={styles.buttonContainer}>
                <Pressable 
                  style={styles.cancel} 
                  android_ripple={{color: '#d9d9d9'}} 
                  onPress={onClose}>
                <Text style={[styles.text, {fontFamily: 'SofiaProBold'}]}>Cancel</Text>
                </Pressable>
                
              </View>
            </View>
          </View>
        </Modal>
      )
    }
    
    export default FancyAlert
    
    Login or Signup to reply.
  2. You can pass also setVisible to the child component, and invoke it with the value you want.

    
    const ViewNote = ({route, navigation}) => {
      const [visible, setVisible] = useState(false);
    
      function visibility(cases) {
        setVisible(cases);
        console.log(cases);
      }
    
      return (
        <View style={styles.noteContainer}>
    
            {/* MODAL */}
            <FancyAlert visible={visible} setVisible={setVisible} />  //ADDED CODE HERE
            <View style={styles.deleteContainer}>
              <Pressable android_ripple={{color: '#d9d9d9'}} onPress={() =>  setVisible(true)}>
                <MaterialIcons style={styles.icon} name='delete' size={40}/>
              </Pressable>
            </View>
    
        </View>
      )
    }
    
    export default ViewNote
    

    and use it as:
    Child Component:

    const FancyAlert = ({visible, setVisible}) => { // IMPORT IT HERE
      const [showAlert, setShowAlert] = useState(false);
    
      return (
        <Modal transparent visible={visible}>
          <View style={styles.modalContainer}>
            <View style={styles.dialogContainer}>
              <Text style={[styles.text, {fontSize: 16}]}>Are you sure you want to delete this note?</Text>
    
              <View style={styles.buttonContainer}>
                <Pressable style={styles.cancel} android_ripple={{color: '#d9d9d9'}} onPress={() => setVisible(false)}> // NOW THIS WORKS
                  <Text style={[styles.text, {fontFamily: 'SofiaProBold'}]}>Cancel</Text>
                </Pressable>
                
              </View>
            </View>
          </View>
        </Modal>
      )
    }
    
    export default FancyAlert
    
    Login or Signup to reply.
  3. You should simply pass the "visibility" function as prop for FancyAlert.
    Your code should be something like that:

    const ViewNote = ({route, navigation}) => {
      const [visible, setVisible] = useState(false);
    
      function visibility(cases) {
        setVisible(cases);
        console.log(cases);
      }
    
      return (
        <View style={styles.noteContainer}>
    
            {/* MODAL */}
            <FancyAlert visible={visible} visibility={visibility} />
            <View style={styles.deleteContainer}>
              <Pressable android_ripple={{color: '#d9d9d9'}} onPress={() =>  visibility(true)}>
                <MaterialIcons style={styles.icon} name='delete' size={40}/>
              </Pressable>
            </View>
    
        </View>
      )
    }
    
    export default ViewNote
    

    And than the FencyAlert component should be:

    const FancyAlert = ({ visible, visibility }) => {
      const [showAlert, setShowAlert] = useState(false);
    
      return (
        <Modal transparent visible={visible}>
          <View style={styles.modalContainer}>
            <View style={styles.dialogContainer}>
              <Text style={[styles.text, {fontSize: 16}]}>Are you sure you want to delete this note?</Text>
    
              <View style={styles.buttonContainer}>
                <Pressable style={styles.cancel} android_ripple={{color: '#d9d9d9'}} onPress={() => visibility(false)}>
                  <Text style={[styles.text, {fontFamily: 'SofiaProBold'}]}>Cancel</Text>
                </Pressable>
                
              </View>
            </View>
          </View>
        </Modal>
      )
    }
    
    export default FancyAlert
    

    This should do the job

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search