我正在使用 codemirror 创建一个组件,但似乎我的代码中有些地方是错误的,因为当我尝试更新我的主要组件的状态时,应用程序破坏了浏览器,我的研究指向一个无限循环,至少我可以在我尝试调试时看到这一点。
希望有人能帮我解决这个问题,也许是我的错,谢谢。
我的主要组成部分:
import React, { Component, PropTypes } from 'react';
import Editor from '../editor';
import Preview from '../preview';
class Playground extends Component {
constructor(props) {
super(props);
this.state = {
code: 'Hi I am a component',
newCode: ''
};
this.handleCodeChange = this.handleCodeChange.bind(this);
}
handleCodeChange(code) {
// Everything works fine until this step, when the component wants to update the state, start the infinite loop
this.setState({ newCode: code });
}
loadCode(code) {
this.refs.editor.setCode(code);
}
render() {
return (
<div>
<Editor
ref='editor'
codeText={this.state.code}
onChange={this.handleCodeChange}
/>
<Preview code={this.state.newCode} />
</div>
);
}
}
Playground.propTypes = {
component: PropTypes.string
};
export default Playground;
我的编辑器组件:
import React, { Component, PropTypes } from 'react';
import style from './style';
import CodeMirror from 'codemirror';
import 'codemirror/mode/javascript/javascript';
class Editor extends Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
componentDidMount() {
this.editor = CodeMirror.fromTextArea(this.refs.editor, {
lineNumbers: this.props.lineNumbers,
matchBrackets: true,
mode: 'javascript',
readOnly: this.props.readOnly,
smartIndent: false,
tabSize: this.props.tabSize,
theme: this.props.theme
});
this.editor.on('change', this.handleChange);
}
componentDidUpdate() {
if ( !this.props.readOnly ) {
this.editor.setValue(this.props.codeText);
}
}
handleChange() {
if ( !this.props.readOnly && this.props.onChange ) {
this.props.onChange(this.editor.getValue());
}
}
render() {
let _className = style.editor;
return (
<div className={ _className }>
<textarea ref="editor" defaultValue={this.props.codeText} />
</div>
);
}
}
Editor.propTypes = {
className: React.PropTypes.string,
codeText: PropTypes.string,
lineNumbers: PropTypes.bool,
onChange: PropTypes.func,
readOnly: PropTypes.bool,
tabSize: PropTypes.number,
theme: PropTypes.string
};
Editor.defaultProps = {
className: '',
lineNumbers: false,
readOnly: false,
tabSize: 2,
theme: 'one-dark'
};
export default Editor;
我的预览组件
import React, { Component, PropTypes } from 'react';
class Preview extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>{this.props.code}</div>
);
}
}
Preview.propTypes = {
code: PropTypes.string
};
export default Preview;
如果您需要更多信息或其他信息,请告诉我。
提前致谢。
解决方案
我从编辑器组件中删除了这段代码
componentDidUpdate() {
if ( !this.props.readOnly ) {
this.editor.setValue(this.props.codeText);
}
}
原因是因为此方法为编辑器设置了一个新值,即更新,然后该过程无限地重新开始,如果您手动加载编辑器的内容,则可以使用此方法,但我不是这种情况。
谢谢安东尼
最佳答案
存在无限循环,因为当 CodeMirror 实例发生变化时,您在编辑器组件中调用了 this.handleChange
。当您此时调用 this.handleChange
时,您更新了主要组件的状态。
然后,当您更新主组件状态时,它会调用编辑器组件的 componentDidUpdate
函数。您设置 CodeMirror 实例的值,它会触发 change
事件,更新主要组件状态,等等。
为避免此行为,只需比较 componentDidUpdate
和 handleChange
中的 codeText
以仅在必要时更新。
关于javascript - ReactJS - 无限循环,setState onChange 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39120394/