React.js中实现点击/提交事件触发递归生成文本框的方案咨询
实现方案
问题原因
你之前触发无限循环的核心原因是在render方法中无条件渲染了
组件:每次组件渲染都会生成新的Textbox实例,新实例渲染时又会再次生成下一个实例,没有触发条件和终止逻辑,最终导致浏览器卡死。return (<Textbox/>)
核心实现思路
给每个Textbox组件新增状态位控制下一级组件的渲染时机,仅当前组件提交事件触发时才生成下一级文本框,同时新增全局停止状态控制递归终止。
完整实现代码
import React, { Component } from "react"; class Textbox extends Component { constructor(props) { super(props); this.state = { value: '', showNext: false, // 控制是否渲染下一级文本框 isStopped: false // 控制是否停止继续生成 }; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); this.handleStop = this.handleStop.bind(this); } handleChange(event) { this.setState({ value: event.target.value }); } handleSubmit(event) { event.preventDefault(); // 已经停止的状态下不生成新的文本框 if (this.state.isStopped || this.props.isStopped) return; alert('A name was submitted: ' + this.state.value); // 提交后才设置为true,渲染下一级文本框 this.setState({ showNext: true }); } handleStop() { // 点击停止后更新状态,终止所有后续生成逻辑 this.setState({ isStopped: true }); } render() { const stopStatus = this.state.isStopped || this.props.isStopped; return ( <div> {/* 仅顶层组件显示停止按钮 */} {this.props.isRoot && <button onClick={this.handleStop} style={{marginBottom: '10px'}}>Exit/Stop</button>} <form onSubmit={this.handleSubmit}> <div> <label> Name: <input type="text" value={this.state.value} onChange={this.handleChange} disabled={stopStatus} /> </label> <input type="submit" value="提交" disabled={stopStatus} /> </div> </form> {/* 只有提交过且未停止的状态下才渲染下一级文本框 */} {this.state.showNext && !stopStatus && <Textbox isStopped={stopStatus} />} </div> ); } } export default Textbox;
使用方式
在父组件中引入并标记为根组件即可:
import Textbox from './Textbox'; function App() { return <Textbox isRoot />; }
逻辑说明
- 初始状态下
showNext为false,不会自动渲染下一级组件,避免了无限递归 - 仅当前组件提交事件触发时,才会修改
showNext状态为true,生成下一级文本框 - 点击顶层的
Exit/Stop按钮后,会把停止状态传递给所有子组件,后续所有文本框都会禁用,也不会再生成新的文本框
内容的提问来源于stack exchange,提问作者everestial
相关产品推荐
相关产品推荐

