Reputation: 155
I am currently implementing a modal window. If I click the icon on the navigation bar, the background is blurred and the modal window appears. I changed the value of passedMake
to false when I clicked X to close the modal window. But even if I click X, the modal window doesn't close. When I checked with console, the value of passedMake
changes to false when I click X, but then value comes out true twice and the modal window doesn't close. The question is why the true value is printed twice after false value is checked when X is clicked. I don't know which part is the problem. I will attach a picture of the value in the console. I erased the unnecessary parts as much as I can to make the code easier to understand. I'd appreciate it if you let me know thanks!
NavigationBar:
this is navigation bar file. I pass the value to parent component if Icon is clicked
import React, { useState } from 'react'
import styled from 'styled-components';
const NavigationBarWrap1 = styled.div`
position: fixed;
flex-direction: column;
box-sizing: border-box;
display: flex;
flex-shrink: 0;
.NavigationBarSection1Wrap2 {
opacity: 1;
display: block;
color: rgb(38,38,38);
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
font-size: 14px;
line-height: 18px;
direction: ltr;
}
.IconWrap3 {
position: relative;
display: block;
}
.IconWrap4 {
text-decoration: none;
color: rgb(0,55,107);
box-sizing: border-box;
display: inline;
background-color: transparent;
cursor: pointer;
}
.IconWrap5 {
border-bottom-left-radius: 24px;
padding-right: 12px;
align-items: center;
padding-top: 12px;
width: 100%;
}
.IconWrap6 {
position: relative;
flex: 0 0 auto;
justify-content: flex-start;
flex-direction: column;
}
.IconWrap7 {
box-sizing: border-box;
height: 24px;
width: 24px;
}
`
function NavigationBar({toParentIsMake,}) {
//state declare
const[make,setMake] = useState(false);
const setTrueMake = () => {
setMake(true)
}
const forMake = (e) => {
setTrueMake();
}
//pass value to parent
toParentIsMake(make);
return (
<NavigationBarWrap1 search={search} profile={profile} alarm={alarm} seeMore={seeMore}>
<div className='NavigationBarWrap2'>
<div className='IconWrap3'>
<div className='IconWrap4'>
<div onClick={(e)=>{forMake();}} className='IconWrap5'>
<div>
<div className='IconWrap6'>
<div className='IconWrap7'>
{make===true?
<>
<svg aria-label="새로운 게시물" class="_ab6-" color="#262626" fill="#262626" height="24" role="img" viewBox="0 0 24 24" width="24"><path d="m12.003 5.545-.117.006-.112.02a1 1 0 0 0-.764.857l-.007.117V11H6.544l-.116.007a1 1 0 0 0-.877.876L5.545 12l.007.117a1 1 0 0 0 .877.876l.116.007h4.457l.001 4.454.007.116a1 1 0 0 0 .876.877l.117.007.117-.007a1 1 0 0 0 .876-.877l.007-.116V13h4.452l.116-.007a1 1 0 0 0 .877-.876l.007-.117-.007-.117a1 1 0 0 0-.877-.876L17.455 11h-4.453l.001-4.455-.007-.117a1 1 0 0 0-.876-.877ZM8.552.999h6.896c2.754 0 4.285.579 5.664 1.912 1.255 1.297 1.838 2.758 1.885 5.302L23 8.55v6.898c0 2.755-.578 4.286-1.912 5.664-1.298 1.255-2.759 1.838-5.302 1.885l-.338.003H8.552c-2.754 0-4.285-.579-5.664-1.912-1.255-1.297-1.839-2.758-1.885-5.302L1 15.45V8.551c0-2.754.579-4.286 1.912-5.664C4.21 1.633 5.67 1.05 8.214 1.002L8.552 1Z"></path></svg>
</>:
<>
<svg aria-label="새로운 게시물" class="_ab6-" color="#262626" fill="#262626" height="24" role="img" viewBox="0 0 24 24" width="24"><path d="M2 12v3.45c0 2.849.698 4.005 1.606 4.944.94.909 2.098 1.608 4.946 1.608h6.896c2.848 0 4.006-.7 4.946-1.608C21.302 19.455 22 18.3 22 15.45V8.552c0-2.849-.698-4.006-1.606-4.945C19.454 2.7 18.296 2 15.448 2H8.552c-2.848 0-4.006.699-4.946 1.607C2.698 4.547 2 5.703 2 8.552Z" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"></path><line fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" x1="6.545" x2="17.455" y1="12.001" y2="12.001"></line><line fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" x1="12.003" x2="12.003" y1="6.545" y2="17.455"></line></svg>
</>}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</NavigationBarWrap1>
)
}
export default NavigationBar;
HomePage.jsx:
and this is homepage file I'm trying to implement modal window. When Icon of navigation bar is clickd, background color becomes blur and modal window appears.
import React, { useEffect } from 'react'
import styled from 'styled-components';
import NavigationBar from '../components/NavigationBar';
import { useState } from 'react';
function HomePage() {
//receive value from chid
const[passedMake,setPassedMake] = useState(false);
const toParentIsMake = (isMakeClick) => {
setPassedMake(isMakeClick)
}
console.log('passedMake' , passedMake)
//if click X, close modal
const noModal = (e) => {
setPassedMake(false)
}
return (
<>
<HomepageWrap>
<NavigationBar toParentIsMake={toParentIsMake} passedMake={passedMake}/>
</HomepageWrap>
<Modal passedMake={passedMake}>
<div onClick={(e)=>{noModal();}} className='X'>
<div className='X2'>
<div className='X3'>
<svg aria-label="닫기" class="x1n2onr6 x1lliihq" color="#ffffff" fill="#ffffff" height="18" role="img" viewBox="0 0 24 24" width="18"><title>닫기</title><polyline fill="none" points="20.643 3.357 12 12 3.353 20.647" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="3"></polyline><line fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="3" x1="20.649" x2="3.354" y1="20.649" y2="3.354"></line></svg>
</div>
</div>
</div>
</Modal>
</>
)
}
export default HomePage;
const HomepageWrap = styled.div`
height: 100%;
box-sizing: border-box;
display: flex;
flex-shrink: 0;
align-items: stretch;
flex-direction: row;
overflow-y: visible;
align-content: stretch;
border-bottom-left-radius: 0;
background-color: rgb(250,250,250);
border-bottom-right-radius: 0;
position: static;
justify-content: space-between;
overflow-x: visible;
align-self: auto;
flex-grow: 0;
border-top-left-radius: 0;
border-top-right-radius: 0;
`
const Modal = styled.div`
display: ${props=>props.passedMake===true?'block':'none'};
position: fixed;
background-color: rgba(0,0,0,0.65);
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 500343;
.X {
top: 10px;
right: 10px;
position: absolute;
cursor: pointer;
}
.X2 {
padding: 8px;
justify-content: center;
box-sizing: border-box;
display: flex;
align-items: center;
}
.X3 {
justify-content: center;
display: flex;
flex-direction: column;
}
`
Upvotes: 0
Views: 101
Reputation: 175
I'm not quite sure what the exact issue is because your code is pretty confusing, but if I were to guess the issue is probably that lone call to toParentShowMake(make)
in NavigationBar
.
It seems to me that that call is supposed to pass an event to HomePage
, which then updates its state to match that of the NavigationBar
; that's not how you're supposed to do it.
You're duplicating the state that controls whether or not the modal should be shown, and that is just asking for problems.
Instead, you should keep the state that controls the modal in HomePage
:
function HomePage () {
const [ showModal, setShowModal ] = useState(false)
const show = () => setShowModal(true)
const hide = () => setShowModal(false)
return (
<>
<HomepageWrap>
<NavigationBar onShowModal={show} />
</HomepageWrap>
<Modal show={showModal}>
<div onClick={hide} className='X'>
{/* ... */}
</div>
</Modal>
</>
)
}
Then in NavigationBar
, accept a callback that will update that state:
function NavigationBar({ onShowModal }) {
return (
<NavigationBarWrap1>
<div onClick={onShowModal} className='IconWrap5'>
{/* ... */}
</div>
</NavigationBarWrap1>
)
}
This way, there's only one place that controls the Modal, the HomePage in which it lives.
Upvotes: 1