前端在div中使用ContentEditable 为react框架,直接使用react的useState会出现数据递归现象及光标便位置,如何正常使用,当前数据为map遍历出来的多个div,不能单纯使用一个ref完整demo
时间: 2024-12-22 08:23:40 浏览: 4
useEditable是一个很小的React钩子,可以使用contenteditable(和magic)将元素转换为完全可渲染和可编辑的内容表面,例如代码编辑器-React开发
在React中使用`ContentEditable`组件并配合`useState`管理内容时,如果遇到数据递归或光标定位问题,可以按照以下步骤处理:
1. **避免数据递归**:
- 当数据是通过`map`遍历得到的多个元素时,你需要对每个单独的元素维护其独立的状态。在`map`函数内部创建一个新的状态(比如`setEditableContent`),而不是共享一个全局的状态变量。
```jsx
function ContentEditableList({ items }) {
const [editables] = useState(items.map((item, index) => ({
content: item.content,
handleEdit: (newContent) => {
setItems(prevItems =>
prevItems.map((i, idx) =>
i.index === index ? { ...i, content: newContent } : i
)
);
},
})));
return (
<div>
{editables.map((editable, idx) => (
<div key={idx}>
<span contentEditable={true} onInput={(e) => editable.handleEdit(e.target.innerText)}>
{editable.content}
</span>
</div>
))}
</div>
);
}
```
2. **光标位置**:
- `ContentEditable`本身并不支持精确控制光标位置,你可以选择使用第三方库如`react-quill`、`draft-js`等来进行更复杂的富文本编辑,它们会提供更好的光标管理和输入事件处理。
3. **Ref示例**:
- 如果需要在单个`div`上使用`ref`来获取焦点或获取输入值,可以创建一个`useRef`对象来引用对应的DOM节点。
```jsx
import React, { useRef, useEffect } from 'react';
function EditableDiv() {
const divRef = useRef(null);
useEffect(() => {
if (divRef.current && divRef.current.focus) {
divRef.current.focus();
}
}, []);
function handleChange(newContent) {
// 更新state或触发其他操作
}
return (
<div ref={divRef} contentEditable onChange={handleChange}>
{/* 输入内容 */}
</div>
);
}
export default EditableDiv;
```
阅读全文