我正在创建一个弹出模式,该模式应该仅在用户首次访问网站时出现。为此,我使用useEffect挂钩执行以下两项操作:1.)检查是否已设置cookie,(如果尚未设置,则将设置cookie)2.)根据该检查,更新isCookie的状态为true / false。
然后我将isCookie状态值作为道具传递给模态组件,模态组件将使用isCookie状态确定是否显示模态。
这是问题所在:模态仅基于useState初始值进行渲染。即使在useEffect中更新了状态之后,模态也不会重新呈现。我可以通过控制台日志确认状态是否正在更新,但是我不知道如何获取重新渲染的模式。
cookie的检查和在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}/>
弹出/模式组件的相关部分:
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)
}
答案 0 :(得分:2)
useEffect
确实通过状态更改重新渲染了模态,但是重新渲染不会重置内部渲染的组件的状态变量(如果您想到的是带有受控组件的表单,那将是非常糟糕的。)只有重新安装才能做到。
因此,当您将模式设置为useState(intialModalState)
时,它将始终取决于其收到的初始道具,而没有其他任何东西。
要在重新渲染发生时将道具同步到状态,您需要在子对象内部有一个useEffect
来监听道具更改:
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]);