英文:
useState doesn't update my setState correctly in next.js
问题
我在英雄部分有一些使用 framer.motion 的动画,我只想在第一次加载时播放。
我想在本地存储中存储一些内容,以跟踪是否显示动画,使用 useState 和 useEffect 进行工作。
useEffect 会像预期的那样影响本地存储,但我不确定为什么我的英雄部分仍然显示相同的内容,就好像 useState 没有改变。
async function Hero() {
const [animate, setAnimate] = useState(true);
useEffect(() => {
if(localStorage.getItem('animate') != null){
localStorage.setItem('animate', 'false')
setAnimate(false)
}else{
localStorage.setItem('animate', 'true')
}
}
}, []);
return (
<div>
<motion.h1 animate={{opacity:1}} initial={animate == true ? {opacity:0} : {opacity:1}}>Some text</motion.h1>
</div>
)
}
export default Hero
在第一次加载时,本地存储中的 'animate' 是 true,然后切换为 false,但它不会影响动画。
我使用了一小段简单的代码来确保它不是来自我的 framer 代码,但结果是一样的
{animate == true?<h1>True</h1>:<h1>False</h1>}
我尝试改变了依赖项数组,但仍然不起作用。
使用以下代码:
async function Hero() {
const [animate, setAnimate] = useState(true);
console.log(animate)
useEffect(() => {
if(localStorage.getItem('animate') != null){
localStorage.setItem('animate', 'false')
setAnimate(false)
}else{
localStorage.setItem('animate', 'true')
}
}, []);
它首先记录 true,然后当我导航到其他地方并返回时,它记录 true,然后无限记录 false(每秒约 1000 次)。
有任何想法吗?
英文:
I have a few animations on my hero section with framer.motion that I want only on the first load.
I wanted to store someting in the local storage to track if yes or not I display the animations, working with a useState and useEffect.
The useEffect does affect the local storage as expected but then I'm not sure why my hero section still display the same thing as if useState didn't change.
async function Hero() {
const [animate, setAnimate] = useState(true);
useEffect(() => {
if(localStorage.getItem('animate') != null){
localStorage.setItem('animate', 'false')
setAnimate(false)
}else{
localStorage.setItem('animate', 'true')
}
}
}, []);
return (
<div>
<motion.h1 animate={{opacity:1}} initial={animate == true ? {opacity:0} : {opacity:1}}>Some text</motion.h1>
</div>
)
}
export default Hero
On the first load 'animate' in the localStorage is true and then switch on false, but it doesn't affect the animation.
I checked with a simple piece of code to be sure it doesn't come from my framer code but it's the same
{animate == true?<h1>True</h1>:<h1>False</h1>}
I tried to change the dependancies array but still doesn't work.
with this code :
async function Hero() {
const [animate, setAnimate] = useState(true);
console.log(animate)
useEffect(() => {
if(localStorage.getItem('animate') != null){
localStorage.setItem('animate', 'false')
setAnimate(false)
}else{
localStorage.setItem('animate', 'true')
}
}, []);
It first logs true than when I navigate elsewhere and come back it logs true then infinite false (like 1000 times a second)
Any idea?
Edit
Here is the full code.
This component is insdide a components direcotry itself inside the app directory.
I don't know why but when I had a useEffect to the component it makes the whole page slow and even crash the window.
'use client'
import {React, useState, useEffect} from 'react'
import Link from 'next/link'
import { IoIosPin } from "react-icons/io";
import { IoMdBus } from "react-icons/io";
import { motion } from "framer-motion"
export default async function Hero() {
const [animate, setAnimate] = useState(true);
useEffect(() => {
if(localStorage.getItem('animate') != null){
localStorage.setItem('animate', 'false')
setAnimate(false)
}else{
localStorage.setItem('animate', 'true')
}
},[])
return (
<div className='px-2 pt-3 mdl:px-8 lgl:px-12 xl:px-16'>
<div className='relative w-full bg-[url("/hero/cabinet-paysage.jpg")] bg-cover bg-center bg-no-repeat sml:min-h-[300px] mdl:min-h-[400px] lg:min-h-[450px] lgl:min-h-[500px]'>
<motion.div className="w-full h-full bg-bgwhite sml:min-h-[300px] mdl:min-h-[400px] lg:min-h-[450px] lgl:min-h-[500px]" animate={{opacity:1}} initial={animate == true ? {opacity:0} : {opacity:1}} transition={{ease: "linear", duration:0.5}}>
<div className=' w-full h-full max-w-[1000px] sml:min-h-[300px] mdl:min-h-[400px] p-5 mx-auto grid grid-cols-1 grid-rows-8 auto-rows-fr auto-cols-fr sml:grid-cols-3 sml:grid-rows-2'>
<div className='row-span-4 flex flex-col justify-center gap-3 mdl:gap-4 lg:gap-5 xl:gap-6 sml:col-start-1 sml:col-end-3 sml:row-span-2 '>
<motion.h1 animate={{opacity:1}} initial={animate == true ? {opacity:0} : {opacity:1}} transition={{delay:0.2, ease: "linear", duration:0.3}}>Some text</motion.h1>
<motion.h2 animate={{opacity:1}} initial={animate == true ? {opacity:0} : {opacity:1}} transition={{delay:0.4, ease: "linear", duration:0.3}}>Some text</motion.h2>
<motion.p className='sml:max-w-[450px] headertext' animate={{opacity:1}} initial={animate == true ? {opacity:0} : {opacity:1}} transition={{delay:0.6, ease: "linear", duration:0.3}}>Le Lorem Ipsum est simplement du faux texte employé dans la composition et la mise en page avant impression. Le Lorem Ipsum est le faux texte et</motion.p>
</div>
<div className='row-span-3 flex flex-col justify-center items-center gap-2 sml:col-start-3 sml:row-span-2'>
<div className='flex justify-center gap-4'>
<motion.div className='flex flex-col items-center w-24 text-center' animate={{opacity:1}} initial={animate == true ? {opacity:0} : {opacity:1}} transition={{delay:0.2, ease: "linear", duration:0.3}}>
<IoIosPin className='reacticons'/>
<p className='headertext'>Some text</p>
</motion.div>
<motion.div className='flex flex-col items-center w-24 text-center' animate={{opacity:1}} initial={animate == true ? {opacity:0} : {opacity:1}} transition={{delay:0.4, ease: "linear", duration:0.3}}>
<IoMdBus className='reacticons'/>
<p className='headertext'>Some text</p>
</motion.div>
</div>
<Link href="/#contact" className='buttonheader inline-block text-center self-center'>
Prendre Rendez-Vous
</Link>
</div>
</div>
</motion.div>
</div>
</div>
)
}
答案1
得分: 1
尝试从函数中移除异步关键字,因为它不会起作用。
英文:
try removing async from the function, because it won't work
function Hero() {
const [animate, setAnimate] = useState(true);
useEffect(() => {
if(localStorage.getItem('animate') != null){
localStorage.setItem('animate', 'false')
setAnimate(false)
}else{
localStorage.setItem('animate', 'true')
}
}
}, []);
return (
<div>
<motion.h1 animate={{opacity:1}} initial={{opacity:animate?0:1}}>Some text</motion.h1>
</div>
)
}
export default Hero```
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论