btholt/complete-intro-to-react-v5

Modal, create Portal

magicishaq opened this issue · 0 comments

When making the modal

<div id="modal" > </div>

the class for modal shows the transparent underlay throughout the whole application (not just when clicking on details).
#modal { background-color: rgba(0, 0, 0, 0.9); position: fixed; left: 0; right: 0; bottom: 0; top: 0; z-index: 10; display: flex; justify-content: center; align-items: center; }

Im not sure how to get rid of this underlay programmatically and showing it on the details page only

Here is my modal module :
`/* eslint-disable react-hooks/rules-of-hooks */
// eslint-disable-next-line react-hooks/rules-of-hooks
import React, { useEffect, useRef } from "react";
import { createPortal } from "react-dom";

const Modal = ({ children }) => {
const elRef = useRef(null);
if (!elRef.current) {
elRef.current = document.createElement("div");
}

useEffect(() => {
const modalRoot = document.getElementById("modal");
modalRoot.appendChild(elRef.current);
return () => modalRoot.removeChild(elRef.current);
}, []);

return createPortal(

{children}
, elRef.current);
};

export default Modal;
`

here is my details module
`
import React from 'react'
import pet from '@frontendmasters/pet'
import {navigate} from '@reach/router'
import Modal from './Modal'
import Carousel from './Carousel'
import ErrorBoundary from './ErrorBoundary'
import ThemeContext from './ThemeContext'
class Details extends React.Component {
constructor(props){
super(props);
this.state = {
loading: true,
showModal: false
}

}


//cant use hooks with classes
componentDidMount (){
    //throw new Error('lol')
    // will show the errorBoundary component
    pet.animal(this.props.id)
    .then( ({animal})=> {
            this.setState(
                {
                    url: animal.url,
                    name: animal.name, 
                    animal: animal.type, 
                    location: `${animal.contact.address.city} - ${animal.contact.address.state}`, 
                    descripton: animal.description, 
                    media: animal.photos,
                    breed: animal.breeds.primary, 
                    loading: false

                }
            )
    }, console.error)
}
toggleModal = () => this.setState({showModal: !this.state.showModal})
adopt = () => navigate(this.state.url)

render () {
    if(this.state.loading){
        return (<h1>loading ... </h1>)
    }else{
        const {animal, breed, location, description, name, media, showModal } = this.state; 

        return (<div className="details">
            <Carousel media={media} /> 
            <div>
                <h1> {name} </h1>
                <h2> {`${animal} - ${breed} - ${location} `}</h2>
                <ThemeContext.Consumer>
                    {(themeHook) => (
                <button onClick={this.toggleModal} style={{backgroundColor: themeHook[0]}}> Adopt {name} </button>
                    )}
                </ThemeContext.Consumer>
                <p>{description}</p>
                {
                    showModal ? (
                        <Modal children = {
                            <div>
                                <h1>Would you like to adopt {name} ? </h1> 
                            <div className="buttons">
                                    <button onClick={this.adopt}>Yes</button>
                                    <button onClick={this.toggleModal}>No Im a Monster </button> 
                                </div> 
                                </div> 
                        }>
                            
                        </Modal>
                    ) : null 
                }
                <img src={this.state.media[0].large} alt={name} ></img> 
                </div> 
            </div> )
    }

}

}

export default function ErrorBoundaryFromDetails (props) {
return (

<Details {...props} />

)
}`

NOt sure about the whole showModal: true .. how does this change the classes or tell where to close the portal?