react卸载和重新安装子组件

IT技术 reactjs ckeditor
2021-04-27 16:03:21

我有一个 npm 导入的组件(CKEditor),它只关心它安装时父组件的状态。即,无论父组件的状态发生什么变化,如果 CKEditor 已经挂载,则 CKEditor 不会反映这些变化。

这对我来说是一个问题,因为当父组件更改其语言属性时,我需要 CKEditor 根据父组件的状态进行更改。

有没有办法让我从父组件卸载并重新安装子组件?例如,有没有办法让我根据父组件的“componentWillReceiveProps”卸载并再次安装子组件?

    import React from 'react';
    import CKEditor from "react-ckeditor-component";

    export default class EditParagraph extends React.Component {
        constructor(props) {
            super(props)
            this.state = {
                // an object that has a different html string for each potential language
                content: this.props.specs.content,
            }
            this.handleRTEChange = this.handleRTEChange.bind(this)
            this.handleRTEBlur = this.handleRTEBlur.bind(this)
        }

        /**
         * Native React method 
         *  that runs every time the component is about to receive new props.
         */
        componentWillReceiveProps(nextProps) {
            const languageChanged = this.props.local.use_lang != nextProps.local.use_lang;
            if (languageChanged) {
                // how do I unmount the CKEditor and remount it ???
                console.log('use_lang changed');
            }
        }

        handleRTEChange(evt) {
            // keeps track of changes within the correct language section
        }

        handleRTEBlur() {
            // fully updates the specs only on Blur
        }

        getContent () {
            // gets content relative to current use language
        }

        render() {
            const content = this.getContent();

            // This is logging the content relative to the current language (as expected), 
            // but CKEditor doesn't show any changes when content changes.
            console.log('content:', content);

            // I need to find a way of unmounting and re-mounting CKEditor whenever use_lang changes.
            return (
                <div>
                    <CKEditor 
                        content={content} 
                        events={{
                            "blur": this.handleRTEBlur,
                            "change": this.handleRTEChange
                        }}
                    />
                </div>      
            )
        }
    }
2个回答

由于 CKEditor 在挂载时只使用“content” prop,当父组件的 local.use_lang 发生变化时,我需要重新渲染组件。

CKEditor 可以通过给它一个key等于应该强制它重新渲染的值prop 来强制重新渲染:

<CKEditor key={this.props.local.use_lang} etc />

这样,每当语言props发生变化时,React 都会创建一个新的 CKEditor。

请记住,我使用此解决方案是因为 CKEditor 是我使用 npm 安装的外部组件库。如果我使用的是我自己的代码,我只会更改编辑器使用其props的方式。但是,由于我拒绝对外部库代码进行更改,因此该解决方案允许我强制重新渲染而无需触及编辑器代码的内部结构。

因为没有检测到变化,所以它不会render()再次调用,因此不会再次调用getContent().

您可以做的是让内容成为状态的一部分(根据您的构造函数,已经是),并检查componentWillReceiveProps()是否use_lang更新。如果是这样,那么您可以通过调用this.setState({...rest, content = getContent()};.

然后你的组件render()函数应该是这样的

<CKEditor 
    content={this.state.content} 
    events={{
        "blur": this.handleRTEBlur,
        "change": this.handleRTEChange
    }}
/>

setState()顺便说一句,通过调用,这将依次触发对 的调用render(),如果检测到任何更改,将显示更改。但请注意,这实际上并不是“重新安装”组件,它只是更新视图。换句话说,componentWillMount()componentDidMount()不会在这种情况下更新状态后调用。取而代之的是,componentWillUpdate()componentDidUpdate()将被调用)。在此处阅读有关组件生命周期的更多信息