You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native使用Redux+Axios时首次启动报undefined,state加载过慢

问题修复方案

核心问题原因

  1. 变量名冲突+暂时性死区报错:props传入的参数命名为data,后续又在组件内声明同名const data,在声明这个变量的内部访问data.users时,会优先指向未完成初始化的本地data变量,触发暂时性死区规则直接返回undefined。
  2. 初始状态无兜底,未处理异步请求前的空状态:reducer初始state.data是空对象,首次渲染时请求还未返回,data.users本身就是undefined,直接调用map方法必然报错。
  3. Reducer状态更新遗漏:GET_DATA_SUCCESS和GET_DATA_FAILURE分支没有将loading重置为false,导致无法通过loading状态判断请求是否完成。
  4. 未做加载状态拦截:组件渲染时没有判断loading状态,请求完成前就直接渲染了需要完整数据的图表组件。

之前删除代码等加载完成再粘贴就正常,是因为此时请求已经返回,data.users已经被赋值,组件重新渲染时不会碰到初始空状态的问题。

修复步骤

1. 调整reducer逻辑

补充loading状态重置,提前初始化兜底字段:

const initialState = {
    data: {
        users: [] // 提前初始化users空数组兜底
    },
    error: null,
    loading: false
}

const xchReducer = (state = initialState, action) => {
    switch (action.type) {
        case xchActions.GET_DATA_BEGIN:
            return {
                ...state,
                loading: true
            }
        case xchActions.GET_DATA_SUCCESS:
            return {
                ...state,
                loading: false, // 请求成功重置loading
                data: action.payload.data
            }
        case xchActions.GET_DATA_FAILURE:
            return {
                ...state,
                loading: false, // 请求失败重置loading
                error: action.payload.error
            }
        default:
            return state
    }
}

export default xchReducer;

2. 调整Home组件逻辑

修改冲突变量名,增加状态拦截判断,补充空值兜底:

const Home = ({
    getData,
    data,
    loading, // 解构拿到loading状态
    error
  }) => {
    useFocusEffect(
      React.useCallback(() => {
        getData()
      }, [])
    )

    function renderHeaderContent() {
      return (
        <View style = {{
            flexDirection: 'row',
            justifyContent: 'flex-start',
            ...Platform.select({
              ios: {
                paddingTop: 40
              }
            })
          }}>
            <View style = {{
              marginTop: 10,
              justifyContent: 'center',
              alignItems: 'center',
              alignContent: 'center',
              flex: 1
            }}>
              {/*  userName加可选链兜底,避免空值报错 */}
              <Text> {data?.userName || ''} </Text>
            </View>
        </View>
      )
    }

    // 变量名不要和props的data重名,改为chartData,加可选链兜底
    const chartData = {
      datasets: [{
        // 可选链+兜底空数组,避免undefined调用map
        data: [...(data?.users?.map(d => d.points) || [])],
        strokeWidth: 2
      }]
    };

    function renderChartContent() {
      // 加载中或者数据为空时显示占位内容,避免渲染空图表报错
      if(loading || !data?.users?.length) {
        return <View style={{width: screenWidth, height:256, justifyContent:'center', alignItems:'center'}}>
          <Text>加载中...</Text>
        </View>
      }
      return (
        <View>
          <LineChart 
            data = {chartData}
            width = {screenWidth}
            height = {256}
            verticalLabelRotation = {30}
            chartConfig = {chartConfig}
            withInnerLines = {0}
            bezier
          />
        </View>
      )
    }

    // 增加错误状态处理
    if(error) {
      return <View style={{flex:1, justifyContent:'center', alignItems:'center'}}>
        <Text>加载失败,请稍后重试</Text>
      </View>
    }

    return (
      <View style = {{
        flex: 1,
        backgroundColor: COLORS.white
      }}>
        {renderHeaderContent()} 
        {renderChartContent()}
      </View>
    )
}

function mapStateToProps(state) {
  return {
    data: state.xchReducer.data,
    error: state.xchReducer.error,
    loading: state.xchReducer.loading,
  }
}

function mapDispatchToProps(dispatch) {
  return {
    getData: () => {
      return dispatch(
        getData()
      )
    }
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Home);

内容的提问来源于stack exchange,提问作者Joseph C

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 10:00:02