如何避免React应用传入null的site对象时触发崩溃
项目问题整理
业务场景说明
- 业务逻辑本身允许
site对象存在合法为null的场景,必须保证该场景下应用不出现崩溃。 - 实际运行中
site以null传入Sites组件时,会直接在排序执行位置触发报错,导致应用中断。 - 按照初步建议修改排序逻辑后,崩溃问题仍未解决。
相关代码片段
崩溃发生的Sites组件核心逻辑
const Sites = ({ isOpen, onClose, site, onChange: onChangeSelectedSite = () => {}, }) => { const preparedSites = useMemo( () => sites .sort(sortSiteSelection(site)) .map(elm => { const arr = [ elm.siteId, elm.city, elm.state, elm.country, elm.address, elm.status, ]; if (nearestSites.length) arr.push( nearestSites.find(s => s.closestSiteId === elm.siteId).distance, ); return arr; }) .sort((a, b) => a[6] - b[6]), [sites, site, nearestSites], ); }
父组件传值逻辑
const SitesChangeButton = ({ site, onChange }) => { <Sites site={site} isOpen={isOpenNew} onClose={onCloseNew} onChange={onChange} /> }
正常的site对象结构
{ siteId, city, state, country, address, status, }
修改后仍失效的排序函数
import { pipeSort } from '../fp'; const nameCompare = (x, y) => x.name.localeCompare(y.name); const cityCompare = (x, y) => x.city.localeCompare(y.city); const compareCountry = s => (x, y) => { if (!s) return 0; if (x.countryCode === s.countryCode && y.countryCode === s.countryCode) return 0; else if (x.countryCode === s.countryCode) return -1; else if (y.countryCode === s.countryCode) return 1; else return x.countryCode.localeCompare(y.countryCode); }; export const sortSiteSelection = selectedSite => { if (!selectedSite) { console.log('NULL FROM SORT SITE'); return 0; } pipeSort(compareCountry(selectedSite), nameCompare, cityCompare); };
现存代码的核心问题
sortSiteSelection空值分支返回值错误:数组的sort()方法要求传入一个接收两个参数、返回比较结果的函数作为参数,当selectedSite为null时函数直接返回数值0,不是合法的排序比较器,依然会触发类型错误。sortSiteSelection非空分支遗漏返回值:传入合法的selectedSite时,代码调用了pipeSort()但没有将其结果返回,函数最终返回undefined,传入sort()方法时同样会触发报错。- 比较器本身缺少空值防护:
nameCompare、cityCompare逻辑中直接调用x.name.localeCompare()等方法,如果站点列表项的对应属性为空,依然会触发空值读取的崩溃。 - 组件内存在潜在的空值读取风险:没有对
site的属性做任何兜底处理,一旦site为null,任何直接访问site.xxx的逻辑都会直接抛错。
内容的提问来源于stack exchange,提问作者Jakub
相关产品推荐
相关产品推荐

