React项目npm run build报useEffect缺少postImage依赖如何修复?
警告原文:Warning: React Hook useEffect has a missing dependency: 'postImage'. Either include it or remove the dependency array. react-hooks/exhaustive-deps
问题修复方案
错误根因
你的代码存在三处Hook用法问题,才触发该警告:
- 违反Hook调用规则:你将
useEffect直接写在了return返回的JSX代码块中,Hook只能在组件顶层作用域调用,不能嵌套在渲染逻辑、循环、条件判断内 - 依赖数组不完整:你在
useEffect中使用了外部变量postImage,但没有将它加入依赖数组,因此ESLint的react-hooks/exhaustive-deps规则抛出警告 - 无效代码冗余:第一个
useEffect仅内部定义了变量remainingImage没有任何业务逻辑,还把内部变量放在依赖数组中,属于完全无效的代码,可直接删除
修复步骤
- 删除无效的第一个
useEffect - 将写在JSX中的
useEffect移到组件顶层,仅用来计算图片总数totalImage - 把图片渲染逻辑从
useEffect中移出,单独封装成渲染函数写在<Carousel>组件内部 - 补全
useEffect的依赖数组,加入用到的postImage变量
修复后完整代码
import Image from 'next/image'; import {useRef} from 'react'; import { useSession } from "next-auth/client"; import {ChatAltIcon,ThumbUpIcon,ShareIcon} from "@heroicons/react/outline"; import{LoveIcon,SadEmojiIcon} from "@heroicons/react/solid"; import InsertEmotionIcon from "@material-ui/icons/InsertEmoticon" import SentimentVeryDissatisfiedIcon from "@material-ui/icons/SentimentVeryDissatisfied"; import FavoriteIcon from "@material-ui/icons/Favorite"; import MoodIcon from "@material-ui/icons/Mood"; import MoodBadIcon from "@material-ui/icons/MoodBad"; import firebase from 'firebase'; import { db, storage } from "../firebases"; import {useEffect,useState} from 'react'; import {useCollection} from "react-firebase-hooks/firestore"; import "react-responsive-carousel/lib/styles/carousel.min.css"; import { Carousel } from 'react-responsive-carousel'; const Post=({id,name,message,email,timestamp,postImage})=>{ const commentRef=useRef(null); const [isShown, setIsShown] = useState(false); const [session]=useSession(); const[totalImage,setTotalImage]=useState(null); const[load,setLoaded]=useState(false); const likePost= async(e)=>{ let min =1; let max = 50; let postId = e.target.getAttribute("id"); console.log(postId) let userId = (Math.floor(Math.random()*(max-min+1))+min); let reaction = e.target.getAttribute("data-reaction"); let item = {postId,userId,reaction}; console.log(reaction); let send = await fetch("http://localhost:8000/api/backend",{ method:'post', body:JSON.stringify(item), headers:{ "Content-Type":'application/json', "Accept":'application/json' }, }).then(response=>{ console.log(response) }) } const[user,loading,error] = useCollection( db.collection("users").orderBy("joined_at","desc") ); const submitComment=async(e)=>{ if (!commentRef.current.value) return; else { console.log("comment") } } const handleEvent=(e)=>{ if(e.detail==2){ setIsShown(true) } else{ setIsShown(false) } } // 移到组件顶层的useEffect,补全依赖 useEffect(()=>{ postImage?.forEach((ele)=>{ ele.forEach((urls)=>{ setTotalImage(urls.url.length); }) }) },[session, postImage]) // 单独提取图片渲染逻辑 const renderPostImages = () => { return postImage?.flatMap((ele) => ele.flatMap((urls) => urls.url.map((url_,index) => ( <div key={index} className="w-full rounded"> <Image src={url_} layout="fill" objectFit="cover" alt="image"/> </div> )) ) ) } return ( <div className="flex flex-col"> <div className="p-5 bg-white mt-5 router-t-2xl shadow-sm"> <div className="flex items-center space-x-2"> <div> <p className="font-medium">{name}</p> { timestamp? <p className="text-xs text-gray-40">{timestamp}</p> :( <p className="text-xs text-gray-40">Loading...</p> ) } </div> </div> <p className="pt-4">{message}</p> </div> <div className="relative h-56 bg-white"> <Carousel> {renderPostImages()} </Carousel> </div> { isShown &&( <div className="flex justify-start items-center bg-white" > <div className=" items-center px-1 p-2 rounded-xl corsor-pointer rounded-none rounded-bl-2xl"> <FavoriteIcon onClick={()=>setIsShown(false)}className="text-red hover:text-red-500"style={{color:"red"}}></FavoriteIcon> </div> <div className=" items-center p-2 px-1 rounded-xl corsor-pointer rounded-none rounded-bl-2xl"> <InsertEmotionIcon onClick={()=>setIsShown(false)}className="text-yellow hover:text-yellow-500" style={{color:"yellow"}}></InsertEmotionIcon> </div> <div className=" items-center p-2 px-1 rounded-xl corsor-pointer rounded-none rounded-bl-2xl"> <SentimentVeryDissatisfiedIcon onClick={()=>setIsShown(false)} className="text-yellow hover:text-yellow-500"style={{color:"yellow"}}></SentimentVeryDissatisfiedIcon> </div> <div className="items-center p-2 rounded-xl corsor-pointer rounded-none rounded-bl-2xl"> <MoodIcon onClick={()=>setIsShown(false)} className="text-yellow hover:text-yellow-500" style={{color:"yellow"}}></MoodIcon> </div> <div className=" items-center px-1 -1 p-2 rounded-xl corsor-pointer rounded-none rounded-bl-2xl"> <MoodBadIcon onClick={()=>setIsShown(false)} className="text-yellow hover:text-yellow-500"style={{color:"yellow"}}></MoodBadIcon> </div> </div> ) } <div className="flex justify-between items-center bg-white shadow-md text-gray-700 border-t mt-5"> <div onDoubleClick={handleEvent} className="flex items-center hover:bg-gray-100 flex-grow justify-content p-2 rounded-xl corsor-pointer rounded-none rounded-bl-2xl"> <ThumbUpIcon className="text-lg sm:text-base h-5 corsor-pointer"onClick={likePost} id={id} data-reaction="like" ></ThumbUpIcon> <span className="cursor-pointer text-2xl text-gray-700">1223</span> </div> <div className="flex items-center hover:bg-gray-100 flex-grow justify-content p-2 rounded-xl corsor-pointer rounded-none"> <ChatAltIcon className="text-lg sm:text-base h-5 corsor-pointer"></ChatAltIcon> <span className="cursor-pointer text-2xl text-gray-700">7777</span> </div> <div className="flex items-center hover:bg-gray-100 flex-grow justify-content p-2 rounded-xl corsor-pointer rounded-none rounded-bl-2xl"> <ShareIcon className="text-lg sm:text-base h-5 corsor-pointer"></ShareIcon> <span className="cursor-pointer text-2xl text-gray-700">312</span> </div> </div> <div className="flex space-x-4 p-4 py-1 items-center bg-white "> {session ? <><Image src={session.user.image} height={40} width={40} layout="fixed"className="rounded-full"alt="image"/> </>:null} <form className="flex flex-1"> <input className="rounded-full h-12 bg-gray-100 flex-grow px-5 focus:outline-none" ref={commentRef} type="text"placeholder="Comment..."/> <button hidden type="submit"onClick={submitComment}></button> </form> </div> <div className="rounded-b-2xl bg-white flex text-gray-40 pb-2 pl-4 "> <small className="mx-auto">Press enter to submit your comment.</small> </div> </div> ) } export default Post;
修改完成后重新执行npm run build,警告就会消失。
内容的提问来源于stack exchange,提问作者Jeevan
相关产品推荐
相关产品推荐

