React设置表单隐藏后再显示,输入框原有值丢失如何解决?
问题根源
你遇到的问题本质来自两个核心原因:
- 用
formVisible && <TextForm />的条件渲染逻辑,当formVisible设为false时,TextForm组件会被直接卸载,组件内部的enteredValue状态会被完全销毁,下次重新显示时组件会重新挂载,本地状态全部丢失。 - 你给input设置了
defaultValue,但子组件的enteredValue初始值没有和传入的props.word绑定,导致新挂载的组件里enteredValue是空值,哪怕输入框显示了默认的旧词汇,提交时取的还是空的enteredValue,自然没有内容更新。
解决方案
提供两种适用不同场景的实现方式:
方案1:调整子组件状态初始化(改动最小,推荐)
只需要修改TextForm组件的状态初始值,将input改为受控组件即可,代码改动极小:
import { useState } from "react"; const TextForm = (props) => { // 初始化状态直接绑定父组件传入的word值 const [enteredValue, setEnteredValue] = useState(props.word); const valueChangeHandler = (e) => { setEnteredValue(e.target.value); }; const submitHandler = (e) => { e.preventDefault(); props.handleUpdateWord(enteredValue); }; return ( <div> <form onSubmit={submitHandler}> {/* 替换defaultValue为value,改成受控组件,保证输入值和状态完全同步 */} <input type="text" onChange={valueChangeHandler} value={enteredValue} /> <button type="submit">更新词汇!</button> </form> </div> ); }; export default TextForm;
这个方案每次表单重新挂载时,都会用父组件最新存储的myWord作为输入框初始值,状态和显示完全同步,提交逻辑不会出问题。
方案2:用CSS控制显隐,不卸载组件(适合需要保留未提交草稿的场景)
如果需要保留用户输入了一半还没提交的内容,不想隐藏表单就丢失草稿,可以调整App.js的渲染逻辑,不让组件卸载,只通过CSS控制显示隐藏:
import "./styles.css"; import { useState } from "react"; import TextForm from "./TextForm"; export default function App() { const [myWord, setMyWord] = useState("default"); const [formVisible, setFormVisible] = useState(false); const handleUpdateWord = (word) => { setMyWord(word); }; const showForm = () => { setFormVisible(true); }; const hideForm = () => { setFormVisible(false); }; return ( <div className="App"> {myWord} {/* 用display控制显隐,不卸载组件,内部状态会一直保留 */} <div style={{display: formVisible ? 'block' : 'none'}}> <TextForm handleUpdateWord={handleUpdateWord} word={myWord} /> </div> <button onClick={showForm}>显示表单</button> <button onClick={hideForm}>隐藏表单</button> </div> ); }
这个方案下TextForm不会被卸载,哪怕用户输入了内容没提交就隐藏表单,再次打开时输入的内容也会完整保留。
内容的提问来源于stack exchange,提问作者Gen Tan
相关产品推荐
相关产品推荐

