useEffect内if语句未触发双分支导致国家列表排序异常
问题根源
Array.sort()是原地排序方法,会直接修改原数组,且返回原数组的引用。React 状态更新依赖引用变化判断是否触发重渲染,直接传入sort返回的原数组引用,会导致setCountryFinal无法触发预期的状态更新,同时直接修改来自useCustomerData的countryList也违反了不可变数据规范。- 两次尝试的代码都没有生成新的数组副本,即使
type取值变化,排序后的数组引用和之前完全一致,effect逻辑看似只触发if分支,实际是状态没有更新导致视图没有变化。
修复方案
排序前先通过展开运算符拷贝原数组,在新数组上执行排序操作,保证每次排序后都是新的数组引用,状态更新可以正常触发:
const { countryList } = useCustomerData(); const [countryFinal, setCountryFinal] = useState<CountryType[]>([]); useEffect(()=>{ // 先拷贝原数组,避免修改原始数据源同时生成新的数组引用 const sortedList = [...countryList]; if(type === 'nationality'){ sortedList.sort((a: CountryObject, b: CountryObject) => a.nationality.localeCompare(b.nationality)) }else { sortedList.sort((a: CountryObject, b: CountryObject) => a.country.localeCompare(b.country)) } setCountryFinal(sortedList); }, [countryList, type])
如果你不需要对排序后的列表做额外的修改操作,完全可以用useMemo替代useState+useEffect的组合,代码更简洁性能也更好:
const { countryList } = useCustomerData(); const countryFinal = useMemo(() => { const sortedList = [...countryList]; if(type === 'nationality'){ return sortedList.sort((a: CountryObject, b: CountryObject) => a.nationality.localeCompare(b.nationality)) } return sortedList.sort((a: CountryObject, b: CountryObject) => a.country.localeCompare(b.country)) }, [countryList, type])
内容的提问来源于stack exchange,提问作者Lutaaya Huzaifah Idris
相关产品推荐
相关产品推荐

