【发布时间】:2022-11-16 01:14:47
【问题描述】:
我正在开发一种工具,用于在工作现场做一些笔记以生成 pdf 报告。
在这个阶段,一切正常(添加、编辑、删除笔记)但是当我重新排序笔记集合时(拖动手柄是灰色按钮) ,React 重新渲染集合的所有 TinyMCE 编辑器,而它应该只更新注释位置。 TinyMCE 编辑器的内容没有改变,只是更新了位置。参见上面的 onSortEnd() 函数。
此操作耗时过长。此外,如果我在页面底部,则重新初始化所有 TinyMCE 编辑器,使页面回到顶部。
所以我的问题是:
有没有办法在不重新初始化所有编辑器的情况下更新编辑器的位置?
找到附上我的界面的屏幕。
我是法国人,对不起我的英语不好。
这里摘录重要代码:
RapportChantier.jsx
export function AddEdit() {
const [rapport, setRapport] = useState({ id: null });
const [notes, setNotes] = useState([]);
const addNote = () => {
notes.push({
uuid: uuidv4(),
id: null,
content: "Ecrivez votre note ici ...",
position: 0,
rapport: "/api/rapport_chantiers/" + rapport.id,
});
setNotes(notes);
};
const removeNote = (id) => {
const filteredNotes = notes.filter((note) => {
if (note.id !== null) {
return note.id !== id;
} else {
return note.uuid !== id;
}
});
setNotes(filteredNotes);
};
const pushNote = (pushedNote) => {
const pushedNoteIndex = notes.findIndex(
(note) => note.uuid === pushedNote.uuid
);
notes[pushedNoteIndex] = pushedNote;
setNotes(notes);
};
const onSortEnd = ({ oldIndex, newIndex }) => {
const reorderedNotes = arrayMove(notes, oldIndex, newIndex);
setNotes(reorderedNotes);
};
const SortableNotes = SortableContainer((props) => {
return (
<div className={props.className}>
{notes.map((note, index) => (
<SortableNote
key={note.id}
note={note}
pushNote={pushNote}
removeNote={removeNote}
index={index}
/>
))}
</div>
);
});
return (
<div className="bg-white" style={{ padding: "30px" }}>
<SortableNotes
className="mb-3"
axis="y"
onSortEnd={onSortEnd}
useDragHandle={true}
lockAxis={"y"}
/>
<button onClick={addNote} className="btn btn-primary btn-sm">
Ajouter une note
</button>
</div>
);
}
笔记.jsx
export const SortableNote = SortableElement(Note);
export default function Note({ note: noteProps, removeNote, pushNote }) {
const editorRef = useRef(null);
const [note, setNote] = useState({ ...noteProps });
const [content, setContent] = useState(noteProps.content);
const [timeoutUpdate, setTimeoutUpdate] = useState(null);
const [hasChanged, setHasChanged] = useState(0);
const updateNote = async () => {
if (!note.id) {
const { status, response } = await sendJsonData(
"/api/notes",
{ ...note, content },
"post"
);
if (status === 201) {
setNote(response);
}
} else {
const { status, response } = await sendJsonData(
"/api/notes/" + note.id,
{ ...note, content },
"patch"
);
if (status === 200) {
setNote(response);
}
}
};
useEffect(() => {
if (hasChanged > 0) {
clearTimeout(timeoutUpdate);
setTimeoutUpdate(setTimeout(updateNote, 1000));
}
}, [hasChanged, content]);
const DragHandle = SortableHandle(() => (
<button
className="btn btn-secondary btn-sm"
onClick={(e) => e.preventDefault()}
>
<span className="icon fa-reorder"></span>
</button>
));
const handleChanges = (editorContent) => {
setContent(editorContent);
setHasChanged(hasChanged + 1);
};
return (
note && (
<div className="mt-3">
<div className="row">
<div className="col-11">
<Editor
tinymceScriptSrc={"/libs/tinymce/tinymce.min.js"}
value={content ?? ""}
onEditorChange={handleChanges}
onInit={(evt, editor) => (editorRef.current = editor)}
init={{
height: 300,
menubar: false,
plugins: [],
toolbar:
"undo redo | blocks | bold italic strikethrough underline forecolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | removeformat",
content_style:
"body { font-family:Helvetica,Arial,sans-serif; font-size:14px }",
}}
/>
</div>
<div className="col-1">
<button className="btn btn-primary btn-sm">
<span className="icon fa-plus"></span>
</button>
<DragHandle />
<button
className="btn btn-danger btn-sm"
onClick={(e) => {
e.preventDefault();
removeNote(note.id ?? note.uuid);
}}
>
<span className="icon fa-remove"></span>
</button>
</div>
</div>
</div>
)
);
}
【问题讨论】:
标签: reactjs tinymce react-sortable-hoc