悠悠楠杉
网站页面
在Web应用中,点击文本直接编辑的需求极为常见(如任务管理、用户资料修改)。传统方案可能需为每个字段编写重复逻辑,而React的组件化思维能优雅解决这一问题。以下是分步实现的可复用模式,包含技术细节与设计考量。
useEditablefunction useEditable(initialValue, onSave) {
const [isEditing, setIsEditing] = useState(false);
const [value, setValue] = useState(initialValue);
const handleEditStart = () => setIsEditing(true);
const handleChange = (e) => setValue(e.target.value);
const handleSave = () => {
onSave(value); // 回调保存逻辑
setIsEditing(false);
};
return { isEditing, value, handleEditStart, handleChange, handleSave };
}EditableFieldfunction EditableField({ initialValue, onSave, children }) {
const { isEditing, value, handleEditStart, ...handlers } =
useEditable(initialValue, onSave);
return (
<div onClick={handleEditStart} className="editable-field">
{isEditing ? (
<input
type="text"
value={value}
onChange={handlers.handleChange}
onBlur={handlers.handleSave}
onKeyDown={(e) => e.key === 'Enter' && handlers.handleSave()}
autoFocus
/>
) : (
<span>{children || value}</span>
)}
</div>
);
}性能优化:
React.memo避免子组件不必要的渲染。lodash.debounce)。样式控制:css
.editable-field:hover {
background: #f5f5f5;
cursor: pointer;
}
校验与反馈:
扩展useEditable,加入错误状态和提示:
const { error, validate } = useValidation(); // 假设存在校验Hook
const handleSave = () => {
if (validate(value)) onSave(value);
else setIsEditing(true); // 保持编辑状态
};jsx
// 用户名称编辑
<EditableField
initialValue={user.name}
onSave={(newName) => updateUserAPI(newName)}
/>
// 多行文本支持
{isEditing ? (
<textarea {...handlers} />
) : (
<p>{value}</p>
)}
handleEditStart中调用e.stopPropagation()。aria-label,确保屏幕阅读器可识别。