简体   繁体   English

组件不会使用“useEffect”钩子在 React 中重新渲染

[英]Component not re-rendering in React using a 'useEffect' hook

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.为此,我使用 useEffect 钩子来做两件事:1.) 检查是否已经设置了 cookie,(如果没有,它将设置 cookie)2.) 基于该检查,更新isCookie 状态为真/假。

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.然后我将 isCookie 状态值作为道具传递给模态组件,该组件将使用 isCookie 状态来确定是否显示模态。

Here's the issue: the modal is rendering based on the useState initial value only.问题是:模态仅基于 useState 初始值进行渲染。 Even after the state has been updated within useEffect, the modal does not re-render.即使在 useEffect 中更新了状态,模态也不会重新渲染。 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: useEffect 中的 cookie 检查和放置:

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. useEffect确实使用状态更改重新渲染模态,但重新渲染不会重置其中渲染的组件的状态变量(如果您想到带有受控组件的表单,那将是可怕的。)只有重新安装才能做到这一点.

Hence, when you set the modal to useState(intialModalState) , it will always be dependent on the initial prop it receives and nothing else.因此,当您将 modal 设置为useState(intialModalState) ,它将始终依赖于它接收到的初始 prop 而没有其他任何东西。

To sync the prop to state when re-rendering happens, you need a useEffect inside the child that listens to prop change:要在重新渲染发生时将 prop 同步到 state,您需要在 child 中使用useEffect来监听 prop 更改:

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]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM