Редактор TinyMCE React выдает «Невозможно установить для свойства onload значение null»

Я использую react-tinymce с приложением create-react-app (последние версии обоих).

Я получаю следующую ошибку при монтировании компонента редактора:

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)

Рассматриваемый раздел находится в 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() возвращает ноль. Это происходит только с перерывами. Иногда редактор загружается корректно. Я должен отметить, что я интегрирую редактор в react-redux-form, как < href="https://davidkpiano.github.io/react-redux-form/docs/guides/custom-controls.html" rel="noreferrer">пользовательский Control компонент.

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>
    );
}

Я инициализирую значение формы из редуктора, который react-redux-form подключается к моему состоянию redux. Редуктор имеет следующую структуру:

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;
    }
}

Иногда редактор загружается нормально, предварительно заполняя описанием статьи из редьюсера. Это говорит мне о том, что проблема является асинхронной и возникает, когда компонент TinyMCE пытается смонтировать до того, как он получил данные от редуктора react-redux-form. Однако я устанавливаю значения по умолчанию в редукторе, поэтому я не уверен, что что-то еще вызывает эту проблему.

Это моя реализация 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)}
    />
}

person andrewhl    schedule 23.10.2017    source источник
comment
Немного поздно, но вы поняли это? У меня та же проблема.   -  person Lee M    schedule 14.02.2018
comment
Это не правильное решение, но лучший способ, который я нашел для решения проблемы, которая, насколько я могу судить, является проблемой библиотек, реализующих TinyMCE для реагирования, - это обернуть ваш компонент редактора (в примере здесь , TinyMCECustom, в ErrorBoundary. См. здесь Я могу опубликовать более длинный ответ, если хотите.   -  person andrewhl    schedule 14.02.2018
comment
Спасибо, Эндрю. Недостатком является то, что этот проект все еще использует React 15.x без возможности обновления. Похоже, мне, возможно, придется найти альтернативное решение, если это возможно.   -  person Lee M    schedule 16.02.2018
comment
Ли, ты нашел какое-нибудь альтернативное решение? У меня такая же проблема, и сейчас у меня нет времени на обновление до React 16.   -  person Simon Christiansen    schedule 19.05.2018


Ответы (1)


Похоже, в TinyMCE была ошибка, из-за которой не удалось удалить частично инициализированный редактор. Я думаю, что ваш компонент демонтируется слишком рано после монтирования.

Ошибка была исправлена ​​в TinyMCE версии 4.7.7: https://github.com/tinymce/tinymce/blob/6b0075fdac4d190614de7d815d067b93300f029d/changelog.txt#L140

person MarkyMarkMcD    schedule 12.12.2018