反应卸载并重新安装子组件
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 而无需触及编辑器代码内部的解决方案。
我有一个 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 而无需触及编辑器代码内部的解决方案。