React应用提交表单后全局状态重置问题排查
表单提交导致React应用状态全重置的原因分析
点击AddProject按钮后,handleAddProject触发将mainArea设为false,展示CreateProject表单组件。提交表单时调用handleSaveProject更新projects状态,却出现整个应用重置、所有状态清空的异常。取消注释handleSaveProject中的setMainArea(undefined)可解决该问题,以下是异常产生的核心原因:
相关组件代码
App组件
import Sidebar from "./components/Sidebar"; import { useState } from "react"; import Project from "./components/Project"; import CreateProject from "./components/CreateProject"; import HomePage from "./components/HomePage"; function App() { const [mainArea, setMainArea] = useState(undefined); const [projects, setProjects] = useState([]); function handleMainArea() { console.log(mainArea) return( <div id = "main-area"> { mainArea ? <Project /> : <CreateProject onSaveProject = {handleSaveProject} onCancel = {handleCancel}/> } </div> ); } function handleSaveProject(projectDetails) { console.log('here') setProjects((projects) => { let tempProjects = [...projects]; tempProjects.push(projectDetails); return tempProjects; }) //setMainArea(undefined) } function handleCancel() { setMainArea(undefined) } function handleAddProject() { setMainArea(false) } return ( <> <Sidebar onAddProject={handleAddProject} projects={[...projects]} /> {mainArea === undefined ? <HomePage /> : handleMainArea()} </> ); } export default App;
CreateProject组件
import { useRef } from "react" export default function CreateProject({onSaveProject, onCancel}) { const titleRef = useRef(); const descrRef = useRef(); const dateRef = useRef(); function onSubmit() { const projectDetails = {}; projectDetails.title = titleRef.current.value; projectDetails.description = descrRef.current.value; projectDetails.date = dateRef.current.value; onSaveProject(projectDetails); } return( <form id="myform" > <div id = "buttonHeader"> <button id = "cancel" onClick = {onCancel}> Cancel </button> <button id = "save" onClick = {onSubmit}> Save </button> </div> <label> TITLE </label> <br></br> <input ref = {titleRef} type = "text" className = "input" id = "titleInput"></input> <br></br> <label> DESCRIPTION </label> <br></br> <textarea ref = {descrRef} type = "text" className = "input" id = "descriptionInput"></textarea> <br></br> <label> DUE DATE </label> <br></br> <input ref = {dateRef} type = "date" id = "dateInput"></input> <br></br> </form> ) }
异常原因解析
- 表单默认提交行为未阻止:HTML中
<form>内的<button>默认类型为submit,点击后会触发表单的默认提交逻辑——向服务器发送请求并刷新整个页面。页面刷新后,React应用的所有内存状态(包括projects、mainArea)都会被清空,表现为整个应用重置。 setMainArea(undefined)的作用:取消注释该行代码后,会立即触发App组件重新渲染,将mainArea设为undefined,此时App会渲染HomePage而非CreateProject组件,CreateProject表单被卸载。表单卸载后,原本的默认提交动作就不会被执行,因此页面不会刷新,状态得以保留。
内容的提问来源于stack exchange,提问作者Swikster
相关产品推荐
相关产品推荐

