React双Select组件渲染异常:关联产品与Coverage数据加载问题
问题:联动Select组件渲染异常
我用两个Select组件实现联动:第一个选择产品,第二个根据选中产品展示对应的Coverage列表。但页面出现渲染异常,注释掉第二个Select后页面能正常运行。
组件代码
<div> <Select onChange={handleChangeSelect} value={TocId} name="ProductID" size="sm"> {TOC.map((type, index) => ( <Select.Option key={type.id} value={type.id}> {type.desc} </Select.Option> ))} </Select> <Select onChange={handleChangeSelect} value={TocId} name="ProductID" size="sm"> {Coverage.map((type, index) => ( <Select.Option key={type.id} value={type.id}> {type.desc} </Select.Option> ))} </Select> </div>
状态与API逻辑
const getCoverage = () => { axios.post(url, data, headers).then(function (response) { if(response.data.Data == 'success') { setCoverage(response.data.Data) } }) } const handleChangeSelect = (e) => { setTocId(e); console.log(TocId); getCoverage(); };
问题分析与修复方案
1. Coverage状态赋值错误
getCoverage里判断response.data.Data == 'success'后,把字符串'success'赋值给了Coverage,字符串无法执行map方法,直接导致渲染报错。
修复:确认接口返回的Coverage列表字段,修正赋值逻辑:
const getCoverage = () => { axios.post(url, { productId: TocId }, headers).then(function (response) { // 假设接口用Code标识成功,Data字段返回Coverage数组 if(response.data.Code === 'success') { setCoverage(response.data.Data || []); // 兜底为空数组 } else { setCoverage([]); } }).catch(() => { setCoverage([]); // 请求失败时兜底 }) }
2. 第二个Select的状态绑定错误
第二个Select的value绑定了产品ID(TocId),且两个Select的name重复为ProductID,属于逻辑错误。
修复:新增coverageId状态绑定第二个Select:
// 新增状态 const [coverageId, setCoverageId] = useState(''); // 第二个Select修改为 <Select onChange={(e) => setCoverageId(e)} value={coverageId} name="CoverageID" size="sm" > {Coverage.map((type, index) => ( <Select.Option key={type.id} value={type.id}> {type.desc} </Select.Option> ))} </Select>
3. useState异步更新导致API参数错误
setTocId是异步操作,在handleChangeSelect里直接调用getCoverage会使用旧的TocId,导致API请求参数错误。
修复:用useEffect监听TocId变化,自动触发请求:
import { useEffect } from 'react'; // ...其他代码 useEffect(() => { if (TocId) { getCoverage(); } }, [TocId]); // 依赖TocId,变化时执行 const handleChangeSelect = (e) => { setTocId(e); setCoverageId(''); // 切换产品时重置Coverage选中状态 };
4. Coverage初始状态兜底
若Coverage初始为undefined或null,第一次渲染时map会报错。
修复:初始化时设为空数组:
const [Coverage, setCoverage] = useState([]);
最终修正后的组件示例
import { useState, useEffect } from 'react'; import axios from 'axios'; import Select from '你的Select组件路径'; const ProductCoverageSelector = () => { const [TocId, setTocId] = useState(''); const [Coverage, setCoverage] = useState([]); const [coverageId, setCoverageId] = useState(''); const TOC = []; // 你的产品列表数据 const getCoverage = () => { const data = { productId: TocId }; axios.post(url, data, headers).then(function (response) { if(response.data.Code === 'success') { setCoverage(response.data.Data || []); } else { setCoverage([]); } }).catch(() => { setCoverage([]); }) } useEffect(() => { if (TocId) { getCoverage(); } }, [TocId]); const handleProductSelect = (e) => { setTocId(e); setCoverageId(''); }; return ( <div> <Select onChange={handleProductSelect} value={TocId} name="ProductID" size="sm" > {TOC.map((type, index) => ( <Select.Option key={type.id} value={type.id}> {type.desc} </Select.Option> ))} </Select> <Select onChange={(e) => setCoverageId(e)} value={coverageId} name="CoverageID" size="sm" disabled={!Coverage.length} > {Coverage.map((type, index) => ( <Select.Option key={type.id} value={type.id}> {type.desc} </Select.Option> ))} </Select> </div> ); }; export default ProductCoverageSelector;
内容的提问来源于stack exchange,提问作者Sulthon Maulana Fathuddin
相关产品推荐
相关产品推荐

