I'm creating a pop-up modal that should only appear on the user's first visit to a website. To do this, I'm using a useEffect hook to do two things: 1.) Check whether a cookie has already been set, (if it hasn't it will set the cookie) 2.) Based on that check, update the isCookie state to true/false.
I'm then passing the isCookie state value as a prop to the modal component, which will use the isCookie state to determine whether to show the modal.
Here's the issue: the modal is rendering based on the useState initial value only. Even after the state has been updated within useEffect, the modal does not re-render. I can confirm the state is updating via console logs, but I can't figure out how to get the modal to re-render.
The cookie check and placement within useEffect:
const [cookie, setCookie] = useState({isCookie:true})
const newCookie = "visited=true; max-age=604800";
useEffect(() => {
if (!document.cookie.split(';').some((item) => item.trim().startsWith('visited='))) { //check to see if a cookie has been placed, if not this is a 'first visit'
setCookie({isCookie:false});
document.cookie = newCookie; //place cookie on first visit
}
}, [])
<PopUp cookie={cookie.isCookie}/>
The relevant part of the pop-up/modal component:
const PopUp = (props) => {
/*if a cookie is present, the initial state of the modal is hidden, otherwise it's set to 'open' or shown*/
const initialModalState = props.cookie ? {open: false} : {open: data.markdownRemark.frontmatter.show}
const [modal, setModal] = useState(initialModalState)
}
useEffect
does re-render the modal with a state change, but re-rendering will not reset the state variables for the component rendered inside it (that would be terrible if you think of a form with a controlled component.) Only remounting can do that.
Hence, when you set the modal to useState(intialModalState)
, it will always be dependent on the initial prop it receives and nothing else.
To sync the prop to state when re-rendering happens, you need a useEffect
inside the child that listens to prop change:
const initialModalState = props.cookie ? {open: false} : {open: data.markdownRemark.frontmatter.show}
const [modal, setModal] = useState(initialModalState)
useEffect(() => {
setModal(props.cookie ? {open: false} : {open: data.markdownRemark.frontmatter.show})
}, [props.cookie]);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.