Create generic modal in React Native

Asked

Viewed 439 times

1

I’m trying to create a Modal component that can be reused in other parts of the application. However I am not managing to carry out the opening control of the same. Follow my attempt:

Modal

 export default class ModalComponent extends Component {
    constructor(props) {
        super(props);

        this.state = { isVisible: this.props.isVisible }
        this.closeModal = this.closeModal.bind(this);
    }

    closeModal() {
        let s = this.state;
        s.isVisible = false;
        this.setState(s);
    }

    render() {
        return (
            <Modal animationType='slide' visible={this.state.isVisible}>
                <TouchableOpacity onPress={this.closeModal}>
                    <Text> Fechar </Text>
                </TouchableOpacity>

                <View style={styles.modal}>
                    <Text> Empresa:  </Text>
                </View>
            </Modal>
        );
    }
}

Use in the main code

export default class Home extends Component {
    constructor(props) {
        super(props);
        this.state = {
            data: [
                { id: "00", name: "Estabelecimento 1" },
                { id: "01", name: "Estabelecimento 2" },
                { id: "02", name: "Estabelecimento 3" },
                { id: "03", name: "Estabelecimento 4" },
                { id: "04", name: "Estabelecimento 5" },
                { id: "05", name: "Estabelecimento 6" },
                { id: "06", name: "Estabelecimento 7" },
                { id: "07", name: "Estabelecimento 8" },
                { id: "08", name: "Estabelecimento 9" },
                { id: "09", name: "Estabelecimento 10" }
            ],

            modalVisible: false
        }

        this.openModal = this.openModal.bind(this);
    }

    // Controla a visibilidade do Modal
    openModal() {
        let s = this.state;
        s.modalVisible = true;
        this.setState(s);
    }


    // Rendereiza os item da lista
    renderItem(item) {
        return (
            <TouchableOpacity onPress={this.openModal} style={styles.item}>
                <Text style={styles.text}> {item.name} </Text>
                <Image style={styles.image} source={require('./images/noimage.png')} />
                <Text> Commodo mollit in ad anim fugiat irure. Fugiat sint ea commodo nulla sunt et eu mollit irure in sit consequat eu.  </Text>

                <ModalComponent data={item} isVisible={this.state.modalVisible} />
            </TouchableOpacity>
        );
    }

    render() {
        return (
            <View style={styles.body}>
                <Image style={styles.headerImg} source={require('./images/400x300.png')} />
                <View style={styles.empresas}>
                    <FlatList data={this.state.data}
                        keyExtractor={item => item.id}
                        numColumns={2}
                        renderItem={({ item }) => this.renderItem(item)} />
                </View>
            </View>
        );
    }
}
  • 1

    Have you tried using the "React-Native-modal library"?

1 answer

0

What I would recommend you do is the following:

1 - Remove the modal from the "renderItem". Leave it at the end of the Flatlist. It will be updated according to the item from the selected list. 2 - Send to the modal component by props the close modal function. This function must be implemented in the parent component.

I made adjustments to your code. The parent component would look like this:

export default class Home extends Component {
    constructor(props) {
        super(props);
        this.state = {
            data: [
                { id: "00", name: "Estabelecimento 1" },
                { id: "01", name: "Estabelecimento 2" },
                { id: "02", name: "Estabelecimento 3" },
                { id: "03", name: "Estabelecimento 4" },
                { id: "04", name: "Estabelecimento 5" },
                { id: "05", name: "Estabelecimento 6" },
                { id: "06", name: "Estabelecimento 7" },
                { id: "07", name: "Estabelecimento 8" },
                { id: "08", name: "Estabelecimento 9" },
                { id: "09", name: "Estabelecimento 10" }
            ],

            modalVisible: false,
			registro: {}
        }
    }

    // Controla a visibilidade do Modal
    openModal = (item) =>  {
        this.setsState({modalVisible:true, item: registro: item});
    }
	
	closeModal() {
        this.setsState({modalVisible:false});
    }

    // Rendereiza os item da lista
    renderItem(item) {
        return (
            <TouchableOpacity onPress={this.openModal(item)} style={styles.item}>
                <Text style={styles.text}> {item.name} </Text>
                <Image style={styles.image} source={require('./images/noimage.png')} />
                <Text> Commodo mollit in ad anim fugiat irure. Fugiat sint ea commodo nulla sunt et eu mollit irure in sit consequat eu.  </Text>
            </TouchableOpacity>
        );
    }

    render() {
        return (
            <View style={styles.body}>
                <Image style={styles.headerImg} source={require('./images/400x300.png')} />
                <View style={styles.empresas}>
                    <FlatList data={this.state.data}
                        keyExtractor={item => item.id}
                        numColumns={2}
                        renderItem={({ item }) => this.renderItem(item)} />
					<ModalComponent data={this.state.registro} isVisible={this.state.modalVisible} fechar={this.closeModal.bind(this)} />	
                </View>
            </View>
        );
    }
}

And the child component would look like this:

export default class ModalComponent extends Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <Modal animationType='slide' visible={this.props.isVisible}>
                <TouchableOpacity onPress={this.props.fechar}>
                    <Text> Fechar </Text>
                </TouchableOpacity>

                <View style={styles.modal}>
                    <Text> Empresa:  </Text>
                </View>
            </Modal>
        );
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.