使用useffect()复制componentDidMount逻辑以在客户端加载外部JavaScript
我正在一个NextJS项目中实现一个富文本编辑器。它没有React组件,并且只在客户端运行,因此我必须从外部源加载JavaScript和CSS文件,并处理SSR。请不要建议使用其他工具,因为这不是一个选项 该工具作为类组件运行良好,但我想将其移植到功能组件中。当我测试功能组件时,它偶尔会工作——也就是说,在我更改文件并保存之后(即使只是添加了一个空间)。但只要我刷新页面,我就失去了编辑器。我以为这是因为组件没有安装,但现在我检查了一下,问题仍然存在 我尝试过各种方法,包括禁用SSR的Next动态导入,但到目前为止,只有下面的类方法起作用(编辑器通过绑定到使用useffect()复制componentDidMount逻辑以在客户端加载外部JavaScript,javascript,reactjs,next.js,Javascript,Reactjs,Next.js,我正在一个NextJS项目中实现一个富文本编辑器。它没有React组件,并且只在客户端运行,因此我必须从外部源加载JavaScript和CSS文件,并处理SSR。请不要建议使用其他工具,因为这不是一个选项 该工具作为类组件运行良好,但我想将其移植到功能组件中。当我测试功能组件时,它偶尔会工作——也就是说,在我更改文件并保存之后(即使只是添加了一个空间)。但只要我刷新页面,我就失去了编辑器。我以为这是因为组件没有安装,但现在我检查了一下,问题仍然存在 我尝试过各种方法,包括禁用SSR的Next动态
元素来工作):
从“React”导入React;
从“./组件/布局”导入布局;
类页扩展了React.Component{
state={isServer:true};
componentDidMount(){
this.MyEditor=require(“../public/static/cool editor.js”);
this.setState({isServer:false});//触发器重新启动程序。
var app=MyEditor(“entry”);//创建editor的实例。
}
渲染(道具){
返回(
);
}
}
导出默认页面;
最后一次尝试功能组件:
import React, { useEffect } from "react";
import Layout from "../components/Layout";
function hasWindow() {
const [isWindow, setIsWindow] = React.useState(false);
React.useEffect(() => {
setIsWindow(true);
return () => setIsWindow(false);
}, []);
return isWindow;
}
const Editor = () => {
useEffect(() => {
const script = document.createElement("script");
script.src =
"http://localhost:3000/static/article-editor/cool-editor.js";
script.async = true;
document.body.appendChild(script);
return () => {
document.body.removeChild(script);
};
}, []);
var app = MyEditor("entry");
return (
<Layout>
<textarea id="entry"></textarea>
</Layout>
);
};
const Page = () => {
const isWindow = hasWindow();
if (isWindow) return <Editor />;
return null;
};
export default Page;
import React,{useffect}来自“React”;
从“./组件/布局”导入布局;
函数hasWindow(){
const[isWindow,setIsWindow]=React.useState(false);
React.useffect(()=>{
setIsWindow(真);
return()=>setIsWindow(false);
}, []);
返回窗口;
}
常量编辑器=()=>{
useffect(()=>{
常量脚本=document.createElement(“脚本”);
script.src=
"http://localhost:3000/static/article-编辑器/cool editor.js”;
script.async=true;
document.body.appendChild(脚本);
return()=>{
document.body.removeChild(脚本);
};
}, []);
var app=MyEdit(“条目”);
返回(
);
};
常量页=()=>{
常量isWindow=hasWindow();
如果(isWindow)返回;
返回null;
};
导出默认页面;
您可以在
标记中使用useRef
挂钩:
const refContainer = useRef(null);
return <textarea ref={refContainer}>
检查此处的代码:我可以建议更改的一些内容:
var-app=MyEditor(“条目”)正在每个渲染上创建代码>。考虑使用<代码> USERFE/COD>作为保持实例变量的方式:
- 在
中,未定义Editor
变量MyEditor
包含一个运行一次的hasWindow
(使用空的依赖项数组),我认为它不需要清理功能。要检查是否停留在浏览器或服务器上,只需使用useffect
const isServer=type of window===“undefined”
- 自定义挂钩应使用前缀
use
const refContainer = useRef(null);
return <textarea ref={refContainer}>
useEffect(() => {
if (refContainer.current) {
refContainer.current.innerHTML = "ref has been mounted";
console.log("hello");
}
}, []);