我在 NextJs 应用程序中动态导入组件时遇到一些问题。我正在尝试导入 Froala 文本编辑器,它支持 React。但是,当我尝试导入它时,出现未定义窗口的错误,因此我使用 next/dynamic 导入它。
所以问题是,这个编辑器不应该在页面上的每次更改时重新加载。不管我做什么,前。改变状态,它会重新渲染组件。它只是闪烁,但仍然无法向客户显示。有没有其他方法我可以使用组件而不是“眨眼”?
这是我的组件:
import FroalaEditor from 'react-froala-wysiwyg';
const Froala = (props: {model: any, onChanged: any}) => {
return (
<div>
<FroalaEditor model={props.model} onModelChange={props.onChanged} config={{
toolbarButtons: ['fullscreen', 'bold', 'italic', 'textColor', 'backgroundColor', 'underline', 'strikeThrough', 'fontFamily', 'fontSize', 'color', 'inlineClass', 'inlineStyle', 'paragraphStyle', 'paragraphFormat', 'align', 'formatOL', 'formatUL', 'outdent', 'indent', 'quote', 'insertLink', 'insertImage', 'insertVideo', 'embedly', 'insertFile', 'insertTable', 'emoticons', 'fontAwesome', 'specialCharacters', 'insertHR', 'selectAll', 'clearFormatting', 'print', 'getPDF', 'spellChecker', 'help', 'html', 'undo', 'redo'],
toolbarButtonsXS: ['bold', 'italic', 'fontFamily', 'fontSize', 'undo', 'redo'],
placeholderText: 'Edit Your Content Here!',
charCounterCount: false,
theme: 'dark',
imageUploadParam: 'image_param',
fileUploadMethod: 'POST',
fileUploadURL: 'http://127.0.0.1:8000/upload_file',
// Set the image upload URL.
imageUploadMethod: 'POST',
imageUploadURL: 'http://127.0.0.1:8000/api/upload/image',
// Set request type.
// Set max image size to 5MB.
imageMaxSize: 5 * 1024 * 1024,
// Allow to upload PNG and JPG.
imageAllowedTypes: ['jpeg', 'jpg', 'png'],
}}/>
</div>
)
}
export default Froala
导入到其他组件将是:
const FroalaEditor = dynamic(() => import('../Froala'), {
ssr: false
});
我在页面上更改了什么并不重要...调度、状态或任何可能导致重新渲染的内容,它都会闪烁。我怎样才能防止这种情况发生?
顺便说一句,如果直接导入组件,会报未定义窗口的错误!
我和从
FroalaEditor
进口的'react-froala-wysiwyg'
有完全相同的闪烁问题。
通过在
index.html
从互联网或本地从 node_modules
导入此包解决了问题,如 here.
<link href='https://cdn.jsdelivr.net/npm/froala-editor@latest/css/froala_editor.pkgd.min.css' rel='stylesheet' type='text/css' />
<script type='text/javascript' src='https://cdn.jsdelivr.net/npm/froala-editor@latest/js/froala_editor.pkgd.min.js'></script>
稍后在反应中,您只需要通过
useEffect
使用空依赖数组在组件的初始加载上启动 Froala 一次。
import { useEffect, useRef, useState } from "react";
export default function App() {
const froalaElementRef = useRef();
const froalaInctanceRef = useRef();
const [counter, setCounter] = useState(1);
useEffect(() => {
froalaInctanceRef.current = new FroalaEditor(
froalaElementRef.current,
{
theme: "dark"
// other froala options
},
function () {
this.html.set("initial text");
}
);
}, []);
return (
<div className="App">
<h3>Froala which does not blink on re-renders</h3>
<button onClick={() => setCounter(counter + 1)}>Update counter to re-render the page</button>
<h2>{counter}</h2>
<button onClick={() =>alert(froalaInctanceRef.current.html.get())}>Get froala content</button>
<div ref={froalaElementRef} style={{ margin: 20 }} />
</div>
);
}
您可以在沙箱中玩 froala,并通过更改计数器强制页面重新呈现。
https://codesandbox.io/s/froala-which-does-not-blink-i9lwrp?file=/src/App.js:0-931
Froala 不会在每次渲染时重新启动,文本也不会闪烁。