反应卸载并重新安装子组件

React unmount and remount child component

我有一个 npm 导入组件 (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>      
            )
        }
    }

因为没有检测到变化,所以不会再调用render(),也就不会再调用getContent()

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

然后您的组件 render() 函数应该如下所示

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

(顺便说一句,通过调用 setState(),这将依次触发对 render() 的调用,如果检测到任何更改,将显示更改。但请注意,这是实际上 'remounting' 不是组件,它只是更新视图。换句话说, componentWillMount()componentDidMount() 在这种情况下更新状态后不会被调用。而是 componentWillUpdate()componentDidUpdate() 将被调用)。 Read more about the component lifecycle here

由于 CKEditor 在挂载时只使用 "content" prop,所以当父组件的 local.use_lang 发生变化时,我需要 re-render 组件。

CKEditor 可以强制 re-render 通过给它一个 key 属性等于应该强制它 re-render:

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

这样,只要语言属性发生变化,React 就会创建一个新的 CKEditor。

请记住,我使用此解决方案是因为 CKEditor 是我使用 npm 安装的外国组件库。如果是我自己使用的代码,我只会更改编辑器使用其道具的方式。然而,由于我拒绝更改外部库代码,这是允许我强制执行 re-render 而无需触及编辑器代码内部的解决方案。