我收到错误Uncaught RangeError: Maximum call stack size exceeded
。如何在我的孩子(Typewriter
)组件中消除此递归函数?我相信我收到此错误是因为我在ComponentWillUpdate()中不断调用函数?我该如何解决?我认为通过添加if条件,这应该是固定的吗?
请参阅下面的代码段。谢谢!
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
typing: true,
};
this.interval = null;
this.handleTyping = this.handleTyping.bind(this);
}
handleTyping(doneTyping) {
if (doneTyping) {
this.setState({ typing: !this.state.typing });
}
}
render() {
return (
<div>
<h3>{this.state.typing ? "TRUE" : "FALSE"}</h3>
<Typewriter text={"typewriter_testing"} typeSpeed={50} handleTyping={this.handleTyping}/>
</div>
);
}
}
class Typewriter extends React.Component {
constructor() {
super();
this.state = {
finalText: '',
doneTyping: false,
}
this.typeWriter = this.typeWriter.bind(this);
}
typeWriter(text, n) {
if (n < (text.length)) {
if (n + 1 == (text.length)) {
let j = text.substring(0, n+1);
this.setState({ finalText: j, doneTyping: !this.state.doneTyping });
n++;
}
else {
let k = text.substring(0, n+1) + '|';
this.setState({ finalText: k });
n++;
}
setTimeout( () => { this.typeWriter(text, n) }, this.props.typeSpeed );
}
}
componentDidMount() {
this.typeWriter(this.props.text, 0);
}
componentWillUpdate(nextProps, nextState) {
if (nextState.doneTyping) {
nextProps.handleTyping(nextState.doneTyping);
}
}
render() {
return (
<div>
{ this.state.finalText }
</div>
);
}
}
ReactDOM.render(<Parent />, app);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="app"></div>
答案 0 :(得分:1)
此组件需要在仅nextProps.handleTyping(nextState.doneTyping);
更改时的确切时间内运行doneTyping
。
在componentWillUpdate
中添加另一个条件并将其检出:
componentWillUpdate(nextProps, nextState) {
if (nextState.doneTyping && (nextState.doneTyping !== this.state.doneTyping)) {
nextProps.handleTyping(nextState.doneTyping);
}
}
代码:
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
typing: true,
};
this.interval = null;
this.handleTyping = this.handleTyping.bind(this);
}
handleTyping(doneTyping) {
if (doneTyping) {
this.setState({ typing: !this.state.typing });
}
}
render() {
return (
<div>
<h3>{this.state.typing ? "TRUE" : "FALSE"}</h3>
<Typewriter text={"typewriter_testing"} typeSpeed={50} handleTyping={this.handleTyping}/>
</div>
);
}
}
class Typewriter extends React.Component {
constructor() {
super();
this.state = {
finalText: '',
doneTyping: false,
}
this.typeWriter = this.typeWriter.bind(this);
}
typeWriter(text, n) {
if (n < (text.length)) {
if (n + 1 == (text.length)) {
let j = text.substring(0, n+1);
this.setState({ finalText: j, doneTyping: !this.state.doneTyping });
n++;
}
else {
let k = text.substring(0, n+1) + '|';
this.setState({ finalText: k });
n++;
}
setTimeout( () => { this.typeWriter(text, n) }, this.props.typeSpeed );
}
}
componentDidMount() {
this.typeWriter(this.props.text, 0);
}
componentWillUpdate(nextProps, nextState) {
if (nextState.doneTyping && (nextState.doneTyping !== this.state.doneTyping)) {
nextProps.handleTyping(nextState.doneTyping);
}
}
render() {
return (
<div>
{ this.state.finalText }
</div>
);
}
}
ReactDOM.render(<Parent />, app);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="app"></div>
&#13;