React中LocalStorage存储值异常:页面空白且值为undefined
React邮件表单LocalStorage存储问题:页面空白+值为undefined的解决方法
问题描述
开发邮件表单时,希望提交后在LocalStorage中存储布尔值以阻止访客重复提交,但出现页面空白且LocalStorage存储值为undefined的问题。调整localStorage.getItem的位置到localStorage.setItem下方后,问题解决。
问题分析
原代码的核心问题出在两个useEffect的执行顺序上:
- 组件首次挂载时,先执行读取LocalStorage的逻辑。如果之前LocalStorage里存的是无效值(比如意外存储的
undefined字符串),JSON.parse("undefined")会直接抛出语法错误,导致组件渲染崩溃,页面空白。 - 原本用来存入初始状态
false的useEffect因为前面的报错无法执行,恶性循环下LocalStorage里始终是无效值。
把读取逻辑移到存储逻辑之后,组件一加载就先把合法的false存进LocalStorage,后续读取时拿到的是有效的JSON格式值,自然避免了解析错误。
修复后的代码
import React,{useRef,useState,useEffect} from 'react' import emailjs from '@emailjs/browser'; import './Style/Contact.css' function Contact() { const form = useRef(); const [isSubmited,setIsSubmited]= useState(false); // 先执行存储逻辑,确保LocalStorage有有效值 useEffect(() => { console.log(isSubmited) localStorage.setItem('DoNotDisturb', JSON.stringify(isSubmited)) },[isSubmited]) // 再读取LocalStorage的值,兼容null的情况 useEffect(() => { const Data = JSON.parse(localStorage.getItem('DoNotDisturb')); if (Data !== null) { // 避免布尔值false被误判为"不存在" setIsSubmited(Data); } },[]) const sendEmail = (e) => { e.preventDefault(); setIsSubmited(true) emailjs.sendForm('Jeremy_kun', 'JeremyPortfolio', form.current, '0Vide87CskT8zVici') .then((result) => { console.log(result.text); }, (error) => { console.log(error.text); }); }; // 结合isSubmited状态禁用表单,直接从UI层面阻止重复提交 return ( <div className='Contact'> <h1>Reach me out</h1> <form className='form' ref={form} onSubmit={sendEmail}> <label>Name</label> <input type="text" name="name" disabled={isSubmited} /> <label>Email</label> <input type="email" name="email" disabled={isSubmited} /> <label>Message</label> <textarea name="message" disabled={isSubmited} /> <input className='sendBtn' type= 'submit' value="Send" disabled={isSubmited} /> </form> <div className="ContactBottom"></div> </div> ) } export default Contact;
额外优化点
- 将判断条件从
if (Data)改为if (Data !== null),避免布尔值false被误判为“不存在”,确保能正确读取到之前存储的未提交状态。 - 给表单元素添加
disabled属性,结合isSubmited状态直接禁用输入和提交按钮,从UI层面彻底阻止重复提交,提升用户体验。
内容的提问来源于stack exchange,提问作者Htet Ah Yan
相关产品推荐
相关产品推荐

