问题描述
我有一些标签显示文本,它们通过检查 <input />
状态是 edit
还是 true
有条件地呈现 false
标签。当 true
时,我会渲染一个 <input />
标记来进行内联编辑,而不是显示文本。
一切正常。唯一的问题是,当一个 <button>
标记将 edit
状态更改为 true 时,不是在点击 Edit 的位置显示用于编辑的输入字段,而是每个标记都呈现其输入领域。
如何仅针对那些通过点击编辑按钮更改了 edit
状态的标记来限制这种输入字段的呈现?
我的代码:
const [ edit,setEdit ] = useState(false);
const isEdit = edit;
<div>
<p>{ !isEdit ? (<span>Email: {userProfile.email} <button onClick={e=>setEdit(!edit)}>Edit</button></span>) : (<span>Email:
<input type="text" placeholder="email"
name="email" onChange={e=>setEmail(e.target.value)}/>
<button type="submit" onClick={addUserEmail}>Save</button></span>
)}
</p>
<p>About: { !isEdit ? (<span> {userProfile.about} <button onClick={e=>setEdit(!edit)}>Edit</button>
</span>) :
(<span>
<input type="text" placeholder="about"
name="about" onChange={e=>setAbout(e.target.value)}
/>
<button type="submit" onClick={addUserAbout}>Save</button>
</span>)
)}
</p>
</div>
解决方法
有几种解决方案,但最简洁的方法可能是将这些可编辑字段分成自己的组件,因为它们每个都有自己的状态。
例如,您可以创建一个与此类似的通用 EditableField 组件:
function EditableComponent({defaultIsEditing = false,renderText,renderInput}) {
const [ isEditing,setIsEditing ] = useState(defaultIsEditing);
if(!isEditing){
//Non-edit mode
return (<span> {renderText()} <button onClick={e=>setEdit(!edit)}>Edit</button></span>);
}
//Edit mode
return renderInput();
}
然后使用它:
<div>
<EditableComponent
renderText={() => <>Email: {userProfile.email}</>}
renderInput={() => (<span>Email:
<input type="text" placeholder="email" name="email" onChange={e=>setEmail(e.target.value)}/>
<button type="submit" onClick={addUserEmail}>Save</button>
</span>)}
/>
{/* ...repeat for all fields */}
</div>
此解决方案可确保您不会一遍又一遍地重复相同的逻辑。对于两个字段,您可能只需要创建两个状态变量(例如 isEdit1、isEdit2)就可以了,但是添加的越多它就会变得越麻烦。
另一种选择是将您正在编辑的输入的名称存储为状态,这将确保一次只编辑一个字段,但您在开始编辑新字段时需要注意保存旧字段