React组件关闭添加生日模态框后为何重置为默认数据?
问题:删除生日后关闭模态框,数据恢复初始状态

我开发了一个简单的生日管理应用,默认包含5条生日数据。删除一条生日记录后,点击“添加生日”按钮会弹出模态框;但点击模态框的“关闭”按钮后,Birthdays组件重新渲染并恢复为5条数据,而我预期应该是4条。请问这是什么原因?
以下是相关组件代码:
App组件
import react, { useState } from "react"; import Birthdays from "./Birthdays"; import BirthayData from "./BirthdayData"; import { AddBirthdayModal, AddBirthdayButton } from "./AddBirthdayModal"; function App() { //Keeping track of all birthdays const [allBirthdays, setAllBirthdays] = useState([...BirthayData]); //keeping track if add birthday modal is displayed const [isAddBirthdayShown, setIsAddBirthdayShown] = useState(false); //Delete selected birthday. const DeleteBirthday = (indx) => { const updatedBirthdays = [...allBirthdays]; updatedBirthdays.splice(indx, 1); setAllBirthdays(updatedBirthdays); }; return ( <> <AddBirthdayModal setIsAddBirthdayShown={setIsAddBirthdayShown} isAddBirthdayShown={isAddBirthdayShown} /> <div className="birthdays-container"> <h2>{allBirthdays.length} Birthdays Today</h2> <div> {allBirthdays.length >= 1 && allBirthdays.map((user, index) => { return ( <Birthdays key={user.id} selfie={user.image} name={user.Name} age={user.AgeTurning} deleteBirthday={DeleteBirthday} index={index} /> ); })} </div> </div> <div> <button className="btn" onClick={() => setAllBirthdays([])}> Clear </button> <AddBirthdayButton setIsAddBirthdayShown={setIsAddBirthdayShown} /> </div> </> ); } export default App;
Birthdays组件
import React from 'react' import "./Birthday.css" export default function Birthdays(props) { return ( <div className="birthday-flex-container"> <div className="image-container"> <img className="user-image center" src={props.selfie} alt={`Selfie of person`} /> </div> <div className="user-info center"> <h4 className="name">{props.name}</h4> <span className="age">{props.age} years</span> </div> <div className="delete-birthday-container"> <span onClick={() => props.deleteBirthday(props.index)}>X</span> </div> </div> ) }
Modal组件
import React from "react"; import "./AddBirthdayModal.css"; function AddBirthdayModal({ setIsAddBirthdayShown, isAddBirthdayShown }) { const showHideClassName = isAddBirthdayShown ? "modal-container display-block" : "modal display-none"; return ( <div className={showHideClassName}> <div className="modal"> <p className="modal-title">Who's Birthday?</p> <div className="form-container"> <form className="birthday-form"> <input type="text" placeholder="Name" /> <br /> <input type="text" placeholder="Age" /> <br /> <label for="myfile">Select a Image: </label> <input type="file" id="myfile" name="myfile" /> <br /> <button onClick={() => setIsAddBirthdayShown(false)}>Close</button> </form> </div> </div> </div> ); } function AddBirthdayButton({ setIsAddBirthdayShown }) { return ( <div> <button className="btn" onClick={() => setIsAddBirthdayShown(true)}> Add Birthday </button> </div> ); } export { AddBirthdayModal, AddBirthdayButton };
问题原因
问题出在模态框内的<button>元素:它位于<form>标签内部,默认type为submit。点击该按钮时会触发表单的默认提交行为,导致页面刷新。页面刷新后,App组件的useState会重新初始化,将allBirthdays重置为初始的5条数据,因此看起来像是数据恢复了。
修复方案
有两种可行的解决方式:
方式1:给按钮指定type="button"
修改Modal组件中的Close按钮,明确设置按钮类型为button,避免触发表单提交:
<button type="button" onClick={() => setIsAddBirthdayShown(false)}>Close</button>
方式2:阻止表单默认提交行为
如果后续需要保留表单提交逻辑,可以在<form>标签上添加onSubmit事件,阻止默认行为:
<form className="birthday-form" onSubmit={(e) => e.preventDefault()}> {/* 表单原有内容 */} <button onClick={() => setIsAddBirthdayShown(false)}>Close</button> </form>
内容的提问来源于stack exchange,提问作者meeshaa
相关产品推荐
相关产品推荐

