I'm using react-tinymce with create-react-app (latest versions of both).
I'm getting the following error when the editor component mounts:
uncaught at handleCall TypeError: Cannot set property 'onload' of null
at p.unbindAllNativeEvents (https://cloud.tinymce.com/stable/tinymce.min.js?apiKey=s057mcau7lzqdzu5tu3vx99qiek91pkj0od7u00dbw6kuk65:18:2293)
at p.remove (https://cloud.tinymce.com/stable/tinymce.min.js?apiKey=s057mcau7lzqdzu5tu3vx99qiek91pkj0od7u00dbw6kuk65:20:9142)
at Object.execCommand (https://cloud.tinymce.com/stable/tinymce.min.js?apiKey=s057mcau7lzqdzu5tu3vx99qiek91pkj0od7u00dbw6kuk65:20:19531)
at Object._remove (http://localhost:3000/static/js/bundle.js:127305:27)
at Object.componentWillUnmount (http://localhost:3000/static/js/bundle.js:127245:10)
The section in question is in tinymce.js:
unbindAllNativeEvents: function() {
var a, b = this;
if (b.delegates) {
for (a in b.delegates)
b.dom.unbind(d(b, a), a, b.delegates[a]);
delete b.delegates
}
b.inline || (b.getBody().onload = null,
b.dom.unbind(b.getWin()),
b.dom.unbind(b.getDoc())),
b.dom.unbind(b.getBody()),
b.dom.unbind(b.getContainer())
}
b.getBody()
is returning null. This only happens intermittently. Sometimes the editor loads correctly. I should note that I am integrating the editor into react-redux-form, as a custom Control
component.
render(): React.Element {
return (
<div>
<input type="file" id="image-upload-tinymce" name="single-image" style={{ display: "none" }}
accept="image/png, image/gif, image/jpeg, image/jpg, image/svg" />
<UIForm
as={Form}
model={this.props.formModel}
onSubmit={(foo) => this.handleSubmit(foo)}
>
<Control
model={this.props.fieldModel}
component={TinyMCECustom}
mapProps={{
content: (props) => props.viewValue,
}}
updateContent={this.props.updateContent}
validators={{
required: val => val && val.length > 10
}}
/>
</UIForm>
</div>
);
}
I am initializing the value of the form from a reducer that react-redux-form
connects to my redux
state. The reducer has the following structure:
export default function reducer(state = initialState, action) {
switch (action.type) {
case articleModule.GET_SUCCESS:
case articleModule.SAVE_SUCCESS: {
const article = action.payload.data;
return {
...state,
description: article.description || '',
uuid: article.uuid,
}
}
default:
return state;
}
}
Sometimes the editor loads just fine, prepopulating with the description of article from the reducer. This suggests to me that the issue is asynchronous, and is happening when the TinyMCE component attempts to mount before it has received the data from the react-redux-form
reducer. I am setting default values in the reducer, however, so I'm not sure if something else is causing this issue.
This is my implementation of TinyMCECustom
:
const filePickerCallback = (callback, value, meta) => {
if (meta.filetype !== 'image') {
return;
}
let input = document.getElementById('image-upload-tinymce');
input.click();
input.onchange = () => {
let file = input.files[0];
let reader = new FileReader();
reader.onload = (e) => {
let img = new Image();
img.src = reader.result;
callback(e.target.result, {
alt: file.name
});
};
reader.readAsDataURL(file);
};
}
const handleEditorChange = (e, props) => {
props.updateContent(e.target.getContent());
};
const handleOnBlur = (e, props) => {
props.updateContent(e.target.getContent());
}
const handleOnKeyup = (e, props) => {
const updateContent = _.debounce(() => props.updateContent(e.target.innerHTML), 300);
updateContent();
}
const TinyMCECustom = (props) => {
return <TinyMCE
content={props.content}
config={{
plugins: ['advlist autolink lists link image charmap print preview hr anchor pagebreak',
'searchreplace wordcount visualblocks visualchars code fullscreen',
'insertdatetime media nonbreaking save table contextmenu directionality',
'emoticons template paste textcolor colorpicker textpattern imagetools codesample toc help'],
toolbar1: 'undo redo | insert | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image',
toolbar2: 'print preview media | forecolor backcolor emoticons | codesample help',
image_advtab: true,
file_browser_callback_types: 'image',
file_picker_callback: filePickerCallback,
branding: false,
height: 400,
}}
{...props}
onChange={(e) => handleEditorChange(e, props)}
onBlur={(e) => handleOnBlur(e, props)}
onKeyup={(e) => handleOnKeyup(e, props)}
/>
}
It looks like TinyMCE had a bug where it failed to remove a partially initialized editor. I think your component is being unmounted too soon after being mounted.
The bug was fixed in TinyMCE version 4.7.7: https://github.com/tinymce/tinymce/blob/6b0075fdac4d190614de7d815d067b93300f029d/changelog.txt#L140
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With