Axios & Redux 请求数据时组件先输出undefined、后续才resolve的问题排查
问题排查与修复
定位到的核心问题
- 状态结构前后不匹配
你给companiesReducer设置的初始状态是空数组[],但不管是匹配GET_COMPANIES分支还是走默认分支,reducer返回的都是展开后的普通对象。这种结构不一致会导致store初始化完成后,companiesReducer下根本不存在companies字段,映射到组件props的companies天然就是undefined。 - 空值判断逻辑失效
你在render里写的判断条件是this.props.companies !== 'undefined',这是拿JS原始值类型的undefined和字符串形式的"undefined"做比较,两个值类型完全不同,判断永远为真,根本起不到过滤打印的作用。 - 未做遍历前的空值兜底
由于初始状态下companies字段不存在,直接执行map操作会直接抛出阻断渲染的错误。
关于连续三次输出undefined的说明
这是完全正常的渲染时序表现,不属于代码异常:
- 组件首次挂载时的第一遍render:此时store刚完成初始化,还未触发
fetchCompanies的异步请求流程,组件从props取到的companies就是初始状态下不存在的undefined- 组件挂载完成进入
componentDidMount后,异步请求处于pending状态的过程中,可能触发2-3次重渲染(来源包括React内部生命周期更新、父组件状态变动等),这时候接口还没返回,状态没有更新,companies依然是undefined- 等axios请求resolve,dispatch对应的action更新reducer存储的
companies字段,触发组件重渲染,这时候打印的才是接口返回的真实业务数据
可直接复用的修复代码
- 对齐reducer的初始状态结构,从根源上避免取到
undefined:
const initialState = { companies: [] } const companiesReducer = (state = initialState, action) => { switch (action.type) { case 'GET_COMPANIES': return { ...state, companies: action.payload } default: // 直接返回原状态即可,不需要无意义的对象展开 return state } } export default companiesReducer;
- 修正render里的判断逻辑,加上数组遍历的兜底:
render(){ // 用真实类型校验替代无效的字符串比较 const { companies } = this.props if(Array.isArray(companies)){ console.log(companies) } // 遍历前做好判断,避免空值报错 const companyDom = Array.isArray(companies) ? companies.map(item => <div key={item.id}>{item.name}</div>) : <div>数据加载中...</div> return <div>{companyDom}</div> }
- 额外注意:当前的store配置虽然能正常运行,但写法可以简化避免兼容问题,不影响当前的功能逻辑。
内容的提问来源于stack exchange,提问作者Blerina Pllana
相关产品推荐
相关产品推荐

