0

我正在尝试使用来自 API 调用的响应填充富文本编辑器 ( tiptap.dev )。setEditorContent在使用数据负载调用钩子后,编辑器内容应该更新。我注意到当我修改本地文件并保存它时,API 数据在 DOM 中呈现(但不是在初始页面加载时)。

export default function EditHandbook() {
  const router = useRouter();
  const user = useUser();
  const { query } = useRouter();

  const [loading, setLoading] = useState(true);
  const [editorContent, setEditorContent] = useState(null);

  // Get handbook by ID
  const id = query.id;
  let handbookText = null;
  function loadDataOnlyOnce() {
    axios
      .get("/api/templater/" + id + "/")
      .then((res) => {
        handbookText = res.data.handbookContent; // the object returned from api/templater/[id].js
      })
      .finally(() => {
        setEditorContent(handbookText);
        setLoading(false);
      })
      .catch((err) => console.log(err));
  }

  useEffect(() => {
    loadDataOnlyOnce();
  }, [id]); // only run once, after id is resolved from router on page load

  const editor = useEditor({
    extensions: [StarterKit],
    onUpdate({ editor }) {
      setEditorContent(editor.getHTML());
    },
    content: editorContent,
  });

  return (
    <div>
      <TextEditorMenubar editor={editor} />
      <EditorContent editor={editor} />
    </div>
  );
}

4

2 回答 2

1

我认为你应该补充:

if (loading) return "something is loading";

return (
  <div>
    <TextEditorMenubar editor={editor} />
    <EditorContent editor={editor} />
  </div>
);

并且不要执行 useEffect(() => setId(id), [id]) 因为您将永远重新渲染。如果您需要,请在 if 后面进行控制

于 2022-02-03T22:57:27.527 回答
1

您应该包装id在 useState 中。这对我有用

const router = useRouter();
const [id, setId] = useState(router.query.id);

useEffect(() => {
    setId(router.query.id);
    // Test if the id is not null
    if (id) {
        loadDataOnlyOnce();
    }
}, [router, id]);

还将路由器对象传递给useEffect因此反应知道在路由器更改时触发该功能。

于 2022-02-03T22:40:53.657 回答