React下拉框联动显示不同表单字段问题求助
React下拉框联动动态显示表单字段的正确实现
接手了一个React申请表单UI开发任务,需求是根据下拉框(选项为Yes/No)的选择,在下拉框下方动态显示不同的表单字段。尝试了两种方式都出问题:
- 直接写if-else条件时,代码内容被直接输出到UI上,没有正确渲染组件
- 定义switchFields函数实现时,导致UI崩溃
原代码(注:原代码存在标签未闭合、语法括号错误,需先修正)
const yes_no_option = [ "Yes", "No", ]; const [application, setField] = React.useState<ProposedInfo>({ status: "" }); // 修正语法错误后的代码 <Modal> <form> <FormField label={<FormattedMessage id="Is this an existing application?" />}> <Dropdown placeholder={intl.formatMessage({ id: "Please select Yes or No" })} options={yes_no_option.map((x: string) => ({ label: x, value: x }))} value={application.status} onItemSelect={(e) => e && setField((prev) => ({ ...prev, status: e.value }))} /> </FormField> {/* 此处需添加动态渲染的字段 */} </form> </Modal>
之前尝试的错误代码分析
直接在JSX中写if-else语句
JSX本质是语法糖,内部只能使用表达式而非语句,直接写if-else会被当作文本输出到UI:// 错误写法 if(application.status == "Yes") <FormField blah, blah/> else <FormField abc/>条件渲染函数语法错误
函数内使用了Python风格的语法(if后无括号、用冒号),属于JS语法错误,直接导致UI崩溃:// 错误写法 function switchFields(){ const test = 1 if test == 1: return <FormField blah, blah/> else: return <FormField abc /> }
正确实现方案
方案一:JSX内使用三元表达式
这是React条件渲染最常用的方式,直接在需要动态渲染的位置嵌入三元表达式:
<Modal> <form> <FormField label={<FormattedMessage id="Is this an existing application?" />}> <Dropdown placeholder={intl.formatMessage({ id: "Please select Yes or No" })} options={yes_no_option.map((x: string) => ({ label: x, value: x }))} value={application.status} onItemSelect={(e) => e && setField((prev) => ({ ...prev, status: e.value }))} /> </FormField> {/* 三元表达式实现动态渲染 */} {application.status === "Yes" ? ( <FormField label="Yes对应的专属字段" name="existingAppField" /> ) : application.status === "No" ? ( <FormField label="No对应的专属字段" name="newAppField" /> ) : null} {/* 未选择时不渲染任何内容 */} </form> </Modal>
方案二:提取正确的条件渲染函数
如果逻辑复杂,可将渲染逻辑提取为组件内的函数,注意遵循JS语法规范:
const yes_no_option = [ "Yes", "No", ]; const [application, setField] = React.useState<ProposedInfo>({ status: "" }); // 正确的条件渲染函数 const renderDynamicFields = () => { if (application.status === "Yes") { return <FormField label="Yes对应的专属字段" name="existingAppField" />; } else if (application.status === "No") { return <FormField label="No对应的专属字段" name="newAppField" />; } return null; // 未选择时返回null,不渲染任何内容 }; <Modal> <form> <FormField label={<FormattedMessage id="Is this an existing application?" />}> <Dropdown placeholder={intl.formatMessage({ id: "Please select Yes or No" })} options={yes_no_option.map((x: string) => ({ label: x, value: x }))} value={application.status} onItemSelect={(e) => e && setField((prev) => ({ ...prev, status: e.value }))} /> </FormField> {/* 调用渲染函数 */} {renderDynamicFields()} </form> </Modal>
方案三:使用变量存储渲染结果
在组件内先根据条件赋值变量,再在JSX中引用该变量:
const yes_no_option = [ "Yes", "No", ]; const [application, setField] = React.useState<ProposedInfo>({ status: "" }); // 根据条件定义要渲染的组件 let dynamicField = null; if (application.status === "Yes") { dynamicField = <FormField label="Yes对应的专属字段" name="existingAppField" />; } else if (application.status === "No") { dynamicField = <FormField label="No对应的专属字段" name="newAppField" />; } <Modal> <form> <FormField label={<FormattedMessage id="Is this an existing application?" />}> <Dropdown placeholder={intl.formatMessage({ id: "Please select Yes or No" })} options={yes_no_option.map((x: string) => ({ label: x, value: x }))} value={application.status} onItemSelect={(e) => e && setField((prev) => ({ ...prev, status: e.value }))} /> </FormField> {/* 引用变量渲染组件 */} {dynamicField} </form> </Modal>
内容的提问来源于stack exchange,提问作者user3782816
相关产品推荐
相关产品推荐

