ReactJS中如何将CascadingDropdown组件数据传递到表单提交函数
解决方案
核心思路是通过父组件向子组件传递回调函数的方式实现子到父的数据通信,具体修改如下:
1. 修改父组件CreateTicket
首先在父组件中定义接收下拉数据的回调方法,通过props传递给CascadingDropdown组件:
function CreateTicket() { const [ticketInput, setTicketInput] = useState({ category_id: '', sub_category_id: '', subject_id: '', other_subject: '', file: '', auto_message: '', }); const handleTicketInput = (e) => { e.persist(); setTicketInput({...ticketInput, [e.target.name]: e.target.value }) } // 新增:接收子组件传递的下拉数据 const handleDropdownChange = (dropdownData) => { setTicketInput(prev => ({ ...prev, ...dropdownData // 合并下拉框的三个字段 })) } const submitTicket = (e) => { e.preventDefault(); const data = { ...ticketInput // 这里直接用ticketInput就包含了下拉数据 } axios.post(`/api/store-ticket`, data).then(res => { console.log(res.data); }) } return ( <div className = "container"> <form onSubmit ={submitTicket}> <input id="emp_name" type="text" name="employee_name" className = "form-control" disabled = "disabled" onChange = {handleTicketInput} value = {empname} /> {/* 把回调函数作为props传给子组件 */} <CascadingDropdown onDropdownChange={handleDropdownChange} /> <input id="form_other_subject" type="text" name="other_subject" disabled = "disabled" className = "form-control" value = {ticketInput.other_subject} onChange = {handleTicketInput} /> </form> </div> ) } export default CreateTicket;
2. 修改子组件CascadingDropdown
在每次下拉值更新、state变更完成后,调用父组件传递的回调方法回传数据:
export class CascadingDropdown extends Component { constructor(props) { super(props) this.state = { category_id: '', sub_category_id: '', subject_id: '', CategoryData: [], SubCategoryData: [], subject: [] } } componentDidMount() { axios.get('/api/fetchCategory').then(response => { this.setState({ CategoryData: response.data }); }); } // 封装公共方法:更新state后回传数据给父组件 updateStateAndNotify = (newState) => { this.setState(newState, () => { // state更新完成后调用父组件的回调 const dropdown_data = { category_id: this.state.category_id, sub_category_id: this.state.sub_category_id, subject_id: this.state.subject_id } // 判断props是否传了回调函数,避免报错 if(this.props.onDropdownChange) { this.props.onDropdownChange(dropdown_data) } }) } ChangeSubCategory = (e) => { this.updateStateAndNotify({ category_id: e.target.value }); axios.get('/api/fetchSubCategory?category_id=' + e.target.value).then(response => { this.setState({ SubCategoryData: response.data, }); }); } ChangeSubject = (e) => { this.updateStateAndNotify({ sub_category_id: e.target.value }); axios.get('/api/fetchSubjects?sub_category_id=' + e.target.value).then(response => { this.setState({ subject: response.data }); }); } storeData = (e) => { this.updateStateAndNotify({ subject_id: e.target.value }); } render() { return ( <div className = "row"> {/* 原有下拉框代码不变 */} </div> ) } } export default CascadingDropdown
实现逻辑说明
- 父组件把修改自身state的方法作为属性传给子组件
- 子组件每次下拉选择更新自身state后,调用这个传入的方法,把最新的下拉数据作为参数传递给父组件
- 父组件收到数据后自动更新自身的
ticketInput状态,提交表单时就可以直接拿到完整的下拉数据
内容的提问来源于stack exchange,提问作者Shruti Upari
相关产品推荐
相关产品推荐

