ajh*_*ery 1 reactjs next.js tiptap
我使用 TipTap 作为我的 React 项目的富文本编辑器,用于更新从下拉列表中选择的产品的描述。
预期结果是编辑器应显示已保存在相应产品数据库中的初始内容。
但是,使用编辑器中的“内容”选项允许我设置初始内容,如果我更改下拉列表中的选项,它不会更新初始内容。
我的编辑器代码:
import { useEditor, EditorContent } from '@tiptap/react';
import StarterKit from '@tiptap/starter-kit';
import Underline from '@tiptap/extension-underline';
import Placeholder from '@tiptap/extension-placeholder';
import TipTapMenubar from './TipTapMenubar';
const TiptapEditor = ({ description, setDescription }) => {
// console.log('description', description);
const sampleDesc = `Describe your product in 4-5 bullet points...
Point #1: this is an explanation of my product.
Point #2: ....`;
const editor = useEditor({
extensions: [
StarterKit,
Underline,
Placeholder.configure({
placeholder: sampleDesc,
}),
],
content: `${description}`,
onUpdate: ({ editor }) => {
const html = editor.getHTML();
setDescription(html);
},
});
return (
<div className='!mt-2 border border-gray-300 shadow rounded'>
<TipTapMenubar editor={editor} />
<EditorContent editor={editor} />
</div>
);
};
export default TiptapEditor;
Run Code Online (Sandbox Code Playgroud)
然后在父组件中调用此编辑器组件来显示数据:
import { useState, useEffect } from 'react';
import Skeleton from 'react-loading-skeleton';
import TiptapEditor from '@/components/common/editor/TiptapEditor';
import InputInlineLabel from '@/components/form/InputInlineLabel';
import LoadingButton from '@/components/form/LoadingButton';
function ProductOptionNameDesc({
product,
selectedOption,
name,
setName,
description,
setDescription,
loading,
handleProductOptionData,
handleProductOptionsDescription,
}) {
const [enableEditor, setEnableEditor] = useState(false);
// console.log('product', product);
// console.log('selectedOption', selectedOption);
// if selectedOption, set name and description from it
useEffect(() => {
if (selectedOption) {
const productOptions = product?.product_options;
productOptions?.map((option) => {
if (option?.id === selectedOption?.id) {
setName(option?.name);
setDescription(option?.description);
}
});
setEnableEditor(true);
}
}, [selectedOption]);
// console.log('description', description);
return (
<div>
<form onSubmit={handleProductOptionData}>
<div className='space-y-4'>
<div className='flex items-center gap-2'>
<label htmlFor='poname' className='text-sm text-gray-600'>
Product option name
</label>
<input
id='poname'
name='poname'
placeholder='product name'
className='w-full rounded p-2 border border-gray-300 text-sm placeholder:text-sm focus:outline-none focus:border-purple-500'
value={name || ''}
onChange={(e) => setName(e.target.value)}
/>
</div>
<div className='space-y-2'>
{enableEditor ? (
<TiptapEditor
description={description}
setDescription={setDescription}
placeholder='Add up to 5 points describing the product...'
/>
) : (
<div>
<Skeleton height={20} />
<Skeleton height={70} />
</div>
)}
</div>
{loading ? (
<LoadingButton />
) : (
<button className='text-sm w-full py-1 px-2 rounded cursor-pointer border border-violet-700 bg-violet-50 hover:bg-violet-100 text-violet-700'>
Update name and description
</button>
)}
</div>
</form>
</div>
);
}
export default ProductOptionNameDesc;
Run Code Online (Sandbox Code Playgroud)
我想要实现的目标:
如果用户在下拉列表中选择棕色,并且数据库中已经为棕色保存了一些初始值,则 useEffect 挂钩会更新描述状态,但是,它不会反映在 Tiptap 编辑器内容中。
小智 8
检查这是否有帮助:将描述变量添加到 useEditor 的依赖数组
const editor = useEditor({
...
},[description]);
Run Code Online (Sandbox Code Playgroud)
您可能希望在编辑器组件内运行效果以使用setContent上面评论中引用的函数。
这看起来像
const editor = useEditor({
...
});
useEffect(() => {
editor.commands.setContent(description);
}, [description]);
Run Code Online (Sandbox Code Playgroud)
通过添加为依赖项来重新渲染编辑器description可能有效,但 1) 更昂贵,2) 可能不会完全按照您想要的方式显示,3) 不会触发onTransaction或您可能依赖的任何 TipTap 回调或状态更改将来。
| 归档时间: |
|
| 查看次数: |
4779 次 |
| 最近记录: |