我创建了一个ReactMap组件,该组件接收mapStateToProps函数调用。除了使用Axios进行ajax调用外,其他所有功能都正常。
mapStateToProps更新上的类需要调用服务器,并将其有效负载添加到组件的状态并更新文本区域。
我从控制台收到的错误是
ReactDOMIDOperations.js:47 Uncaught RangeError: Maximum call stack size exceeded
以下是我到目前为止的内容。谁能告诉我如何解决此问题?
import React from "react";
import { connect } from "react-redux";
import ApiCalls from "../../../utils/ApiCalls";
const mapStateToProps = state => {
return { passFilePath: state.passFilePath };
};
/**
* This component is a template to display
* widgets of information
*/
class IdeTextEditorClass extends React.Component {
constructor() {
super();
this.state = {
newData: [],
pathData: []
}
}
/**
* Received request from server add it to
* react component so that it can be rendered
*/
componentDidUpdate() {
try {
this.setState({ pathData: this.props.passFilePath[this.props.passFilePath.length - 1] });
} catch (err) {
this.setState({ pathData: '' });
}
console.log('path', this.state.pathData.data);
ApiCalls.readSassFile(this.state.pathData.data)
.then(function (serverData) {
this.setState({ newData: serverData[0].data })
}.bind(this));
}
render() {
try {
this.state.newData
} catch (err) {
this.setState({ newData: '' });
}
return (
<fieldset>
<input type="text" value={this.state.pathData.data} />
<textarea id="ide-text-area" name="ide-text-area" value={this.state.newData} /></fieldset>
)
}
}
const IdeTextEditor = connect(mapStateToProps)(IdeTextEditorClass);
export default IdeTextEditor;
答案 0 :(得分:0)
class IdeTextEditorClass extends React.Component {
constructor() {
super();
/*
based on your original code it seems the default data should be empty string ,as you set them to be empty string when you cannot get data from server.
*/
this.state = {
newData: '',
pathData: ''
}
}
/**
* Received request from server add it to
* react component so that it can be rendered
*/
componentDidMount() {
try {
this.setState({ pathData: this.props.passFilePath[this.props.passFilePath.length - 1] });
} catch (err) {
this.setState({ pathData: '' });
}
console.log('path', this.state.pathData.data);
ApiCalls.readSassFile(this.state.pathData.data)
.then(function (serverData) {
this.setState({ newData: serverData[0].data })
}.bind(this));
}
render() {
//by default your newData is already empty string. so skip the checking here.
let path = this.state.pathData ? this.state.pathData.data : '';
return (
<fieldset>
<input type="text" value={path} />
<textarea id="ide-text-area" name="ide-text-area" value={this.state.newData} /></fieldset>
)
}
}
说明:
主要更改是将componentDidUpdate
更改为componentDidMount
。
将数据初始化逻辑放在componentDidMount
中是因为:
仅调用一次,因此避免了注释中提到的无休止的更新循环。另外,通常在这里需要初始化逻辑。
此方法在初始渲染之后被调用,因此您至少可以在等待数据期间(从服务器)向用户显示某些内容。例如,在您的render
方法中,您可以检查newData
,如果不可用,则显示一个加载图标。然后React调用componentDidMount
,并获取数据->更新状态->再次触发渲染->使用从服务器获取的新数据显示输入/文本区域。当然,如果您不想打扰显示加载图标,那也很好,因为当ajax调用返回时,您的视图可能会快速更新。