如何在 React 中实现 TinyMCE 到 Shared Textarea 和 Return 它的更新状态?
How to implement TinyMCE to Shared Textarea and Return its Updated State in React?
首先,我正在尝试将 tinyMCE 实现到来自 react-bootstrap 的组件。
所述组件是'dynamic'。它可以是我想要的任何类型的输入,但是当我尝试将它用作带有 tinyMCE 的文本区域时,状态不会 return 来自所述输入的任何数据并且我的数据库更新失败(通过艰难的方式学习)。
我使用它的第一个组件叫做 Edit.js。此输入应将新值存储在 producerData 上,但仅当我不初始化 tinyMCE 时才这样做。
const handleChange = (name) => (e) => {
setIsBlocking(e.target.value.length > 0)
setProducerData({ ...producerData, [name]: e.target.value })
};
<FormInput
id={`text`}
name={`text`}
asType={`textarea`}
handleChange={handleChange('text')}
value={text}
plugins={`toolbar`}
/>
话虽如此,这里是FormInput组件。我之前提到过它可以工作,但不一定与 tinyMCE 一起使用(这就是我目前评论它的原因),这正是我需要的:
import React from 'react'
// HELPERS
import { useScript } from '../../helpers/utilities'
// TINYMCE
import Form from 'react-bootstrap/Form'
const FormInput = ({
id = ``,
name = ``,
type = ``,
asType = ``,
placeholder = `Write here...`,
value = ``,
handleChange,
plugins = ``,
classStr = ``,
required = false,
disabled = false,
ariaLabel = ``,
ariaDescribedby = ``,
autoComplete = ``,
children,
}) => {
// useScript(
// 'tinyMCE',
// `https://cdnjs.cloudflare.com/ajax/libs/tinymce/5.6.2/tinymce.min.js`,
// 'origin',
// 'head',
// false
// );
// if (asType === `textarea`) {
// window?.tinymce?.init({
// selector: `textarea#${id}`,
// // skin: `bootstrap`,
// branding: false,
// height: 300,
// plugins: `toc pagebreak charmap textpattern imagetools ${plugins}`,
// });
// }
return (
<Form.Control
{...{
...(id && { id: id }),
...(name && { name: name }),
...(type && { type: type }),
...(asType && { as: asType }),
...(placeholder && { placeholder: placeholder }),
...(handleChange && { onChange: handleChange }),
...(value && { value: value }),
...(classStr && { className: classStr }),
...(required && { required: required }),
...(disabled && { disabled: disabled }),
...(ariaLabel && `aria-label=${ariaLabel}`),
...(ariaDescribedby && `aria-describedby=${ariaDescribedby}`),
...(autoComplete && { autoComplete: autoComplete }),
}}
>
{children && children}
</Form.Control>
)
}
export default FormInput
再一次,如果我没有很好地解释自己:上面的代码本身可以工作,但我希望它与 TinyMCE 一起工作
这里有人用过react-bootstrap和tinyMCE吗?谢谢!
最后这就是我的结局:
import React from 'react';
import 'tinymce/tinymce';
import 'tinymce/icons/default';
import 'tinymce/themes/silver';
import 'tinymce/plugins/paste';
import 'tinymce/plugins/link';
import 'tinymce/plugins/image';
import 'tinymce/plugins/table';
import 'tinymce/skins/ui/oxide/skin.min.css';
import 'tinymce/skins/ui/oxide/content.min.css';
import 'tinymce/skins/content/default/content.min.css';
import { Editor } from '@tinymce/tinymce-react';
import ReactHtmlParser from 'react-html-parser';
// HELPERS
import { useScript } from '../../helpers/utilities';
const FormInput = ({
id = ``,
name = ``,
value = ``,
handleChange,
plugins = ``,
isRequired = false
}) => {
useScript(
'tinyMCE',
`https://cdnjs.cloudflare.com/ajax/libs/tinymce/5.6.2/tinymce.min.js`,
'origin',
'head',
false
);
const parseEditorData = (content, editor) => {
//content is the current value of the text editor
// editor is an object that holds the html element that in this case is the text area where the name prop will be stored.
const { targetElm } = editor;
// This name value references the prop that you pass as textAreaName (content in your case)
const { name } = targetElm;
// This function returns an object that your handle change can parse correctly
return {
target: {
name,
value: content
}
};
};
return (
<Editor
apiKey={process.env.TINIYMCE_APIKEY}
textareaName={name}
initialValue={`${ReactHtmlParser(value)}`}
init={{
selector: `textarea#${id}`,
skin: `bootstrap`,
branding: false,
height: 300,
plugins: `image link advcode media powerpaste codesample preview wordcount visualchars toc pagebreak charmap textpattern imagetools ${plugins}`,
autoresize_bottom_margin: 50,
textpattern_patterns: [
{ start: '*', end: '*', format: 'italic' },
{ start: '**', end: '**', format: 'bold' },
{ start: '#', format: 'h1' },
{ start: '##', format: 'h2' },
{ start: '###', format: 'h3' },
{ start: '####', format: 'h4' },
{ start: '#####', format: 'h5' },
{ start: '######', format: 'h6' },
{ start: '1. ', cmd: 'InsertOrderedList' },
{ start: '* ', cmd: 'InsertUnorderedList' },
{ start: '- ', cmd: 'InsertUnorderedList' }
]
}}
onChange={(content, editor) =>
handleChange(parseEditorData(content.level.content, editor))
}
outputFormat={`text`}
required={isRequired}
/>
);
};
export default FormInput;
用法:
import TinyMCE from '../../../layout/TinyMCE';
<TinyMCE
id={`text`}
name={`text`}
handleChange={handleChange('text')}
value={text}
plugins={`toolbar`}
isRequired={true}
/>
首先,我正在尝试将 tinyMCE 实现到来自 react-bootstrap 的组件。
所述组件是'dynamic'。它可以是我想要的任何类型的输入,但是当我尝试将它用作带有 tinyMCE 的文本区域时,状态不会 return 来自所述输入的任何数据并且我的数据库更新失败(通过艰难的方式学习)。
我使用它的第一个组件叫做 Edit.js。此输入应将新值存储在 producerData 上,但仅当我不初始化 tinyMCE 时才这样做。
const handleChange = (name) => (e) => {
setIsBlocking(e.target.value.length > 0)
setProducerData({ ...producerData, [name]: e.target.value })
};
<FormInput
id={`text`}
name={`text`}
asType={`textarea`}
handleChange={handleChange('text')}
value={text}
plugins={`toolbar`}
/>
话虽如此,这里是FormInput组件。我之前提到过它可以工作,但不一定与 tinyMCE 一起使用(这就是我目前评论它的原因),这正是我需要的:
import React from 'react'
// HELPERS
import { useScript } from '../../helpers/utilities'
// TINYMCE
import Form from 'react-bootstrap/Form'
const FormInput = ({
id = ``,
name = ``,
type = ``,
asType = ``,
placeholder = `Write here...`,
value = ``,
handleChange,
plugins = ``,
classStr = ``,
required = false,
disabled = false,
ariaLabel = ``,
ariaDescribedby = ``,
autoComplete = ``,
children,
}) => {
// useScript(
// 'tinyMCE',
// `https://cdnjs.cloudflare.com/ajax/libs/tinymce/5.6.2/tinymce.min.js`,
// 'origin',
// 'head',
// false
// );
// if (asType === `textarea`) {
// window?.tinymce?.init({
// selector: `textarea#${id}`,
// // skin: `bootstrap`,
// branding: false,
// height: 300,
// plugins: `toc pagebreak charmap textpattern imagetools ${plugins}`,
// });
// }
return (
<Form.Control
{...{
...(id && { id: id }),
...(name && { name: name }),
...(type && { type: type }),
...(asType && { as: asType }),
...(placeholder && { placeholder: placeholder }),
...(handleChange && { onChange: handleChange }),
...(value && { value: value }),
...(classStr && { className: classStr }),
...(required && { required: required }),
...(disabled && { disabled: disabled }),
...(ariaLabel && `aria-label=${ariaLabel}`),
...(ariaDescribedby && `aria-describedby=${ariaDescribedby}`),
...(autoComplete && { autoComplete: autoComplete }),
}}
>
{children && children}
</Form.Control>
)
}
export default FormInput
再一次,如果我没有很好地解释自己:上面的代码本身可以工作,但我希望它与 TinyMCE 一起工作
这里有人用过react-bootstrap和tinyMCE吗?谢谢!
最后这就是我的结局:
import React from 'react';
import 'tinymce/tinymce';
import 'tinymce/icons/default';
import 'tinymce/themes/silver';
import 'tinymce/plugins/paste';
import 'tinymce/plugins/link';
import 'tinymce/plugins/image';
import 'tinymce/plugins/table';
import 'tinymce/skins/ui/oxide/skin.min.css';
import 'tinymce/skins/ui/oxide/content.min.css';
import 'tinymce/skins/content/default/content.min.css';
import { Editor } from '@tinymce/tinymce-react';
import ReactHtmlParser from 'react-html-parser';
// HELPERS
import { useScript } from '../../helpers/utilities';
const FormInput = ({
id = ``,
name = ``,
value = ``,
handleChange,
plugins = ``,
isRequired = false
}) => {
useScript(
'tinyMCE',
`https://cdnjs.cloudflare.com/ajax/libs/tinymce/5.6.2/tinymce.min.js`,
'origin',
'head',
false
);
const parseEditorData = (content, editor) => {
//content is the current value of the text editor
// editor is an object that holds the html element that in this case is the text area where the name prop will be stored.
const { targetElm } = editor;
// This name value references the prop that you pass as textAreaName (content in your case)
const { name } = targetElm;
// This function returns an object that your handle change can parse correctly
return {
target: {
name,
value: content
}
};
};
return (
<Editor
apiKey={process.env.TINIYMCE_APIKEY}
textareaName={name}
initialValue={`${ReactHtmlParser(value)}`}
init={{
selector: `textarea#${id}`,
skin: `bootstrap`,
branding: false,
height: 300,
plugins: `image link advcode media powerpaste codesample preview wordcount visualchars toc pagebreak charmap textpattern imagetools ${plugins}`,
autoresize_bottom_margin: 50,
textpattern_patterns: [
{ start: '*', end: '*', format: 'italic' },
{ start: '**', end: '**', format: 'bold' },
{ start: '#', format: 'h1' },
{ start: '##', format: 'h2' },
{ start: '###', format: 'h3' },
{ start: '####', format: 'h4' },
{ start: '#####', format: 'h5' },
{ start: '######', format: 'h6' },
{ start: '1. ', cmd: 'InsertOrderedList' },
{ start: '* ', cmd: 'InsertUnorderedList' },
{ start: '- ', cmd: 'InsertUnorderedList' }
]
}}
onChange={(content, editor) =>
handleChange(parseEditorData(content.level.content, editor))
}
outputFormat={`text`}
required={isRequired}
/>
);
};
export default FormInput;
用法:
import TinyMCE from '../../../layout/TinyMCE';
<TinyMCE
id={`text`}
name={`text`}
handleChange={handleChange('text')}
value={text}
plugins={`toolbar`}
isRequired={true}
/>