Close react native modal by clicking on overlay?

Another solution:

// Modal.js
import React from 'react';
import {
  TouchableWithoutFeedback,
  StyleSheet,
  Modal,
  View,
} from 'react-native';
import t from 'prop-types';


class MyModal extends React.Component {
  static propTypes = {
    children: t.node.isRequired,
    visible: t.bool.isRequired,
    dismiss: t.func.isRequired,
    transparent: t.bool,
    animationType: t.string,
  };

  static defaultProps = {
    animationType: 'none',
    transparent: true,
  };

  render() {
    const { props } = this;
    return (
      <View>
        <Modal
          visible={props.visible}
          transparent={props.transparent}
          onRequestClose={props.dismiss}
          animationType={props.animationType}
        >
          <TouchableWithoutFeedback onPress={props.dismiss}>
            <View style={styles.modalOverlay} />
          </TouchableWithoutFeedback>

          <View style={styles.modalContent}>
            {props.children}
          </View>
        </Modal>
      </View>
    );
  }
}


const styles = StyleSheet.create({
  modalContent: {
    flex: 1,
    justifyContent: 'center',
    margin: '5%',
  },
  modalOverlay: {
    position: 'absolute',
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
    backgroundColor: 'rgba(0,0,0,0.5)'
  },
});


export default MyModal;

Usage example:

// SomeScreen.js
import React from 'react';
import { View, Text, Button } from 'react-native';

import Modal from './Modal';


class SomeScreen extends React.Component {
  state = {
    isModalVisible: false,
  };

  showModal = () => this.setState({ isModalVisible: true });
  hideModal = () => this.setState({ isModalVisible: false });

  render() {
    return (
      <View>
        <Button onPress={this.showModal} />
        <Modal
          visible={this.state.isModalVisible}
          dismiss={this.hideModal}
        >
          <Text>Hello, I am modal</Text>
        </Modal>
      </View>
    );
  }
}

If I understood correctly, you want to close the modal when the user clicks outside of it, right ?

If yes, I searched for this some time ago and the only solution that I remember was this one (which is the one that I've been using so far):

render() { 
  if (!this.state.modalVisible)
    return null
  return (
     <View>
        <Modal 
          animationType="fade"
          transparent={true}
          visible={this.state.modalVisible}
          onRequestClose={() => {this.setModalVisible(false)}}
        >
          <TouchableOpacity 
            style={styles.container} 
            activeOpacity={1} 
            onPressOut={() => {this.setModalVisible(false)}}
          >
            <ScrollView 
              directionalLockEnabled={true} 
              contentContainerStyle={styles.scrollModal}
            >
              <TouchableWithoutFeedback>
                <View style={styles.modalContainer}>
                  // Here you put the content of your modal.
                </View>
              </TouchableWithoutFeedback>
            </ScrollView>
          </TouchableOpacity>   
        </Modal> 
     </View>
  )
} 

// Then on setModalVisible(), you do everything that you need to do when closing or opening the modal.
setModalVisible(visible) {
    this.setState({
        modalVisible: visible,
    })
}

Explanation

This is basically using a TouchableOpacity in the whole screen to get when the user clicks to close the modal. The TouchableWithoutFeedback is to avoid the TouchableOpacity to work inside of the Modal.

If you have a better solution, please share here.