如何从Axios get请求中提取数据并在React组件中正常获取?
问题排查与修复方案
存在的问题清单
- 异步请求放在了
render方法中执行,导致触发无限重渲染,同时异步请求返回时序不可控 mapStateToProps未将Redux Store中存储的用户信息映射到组件Props,无法直接从组件侧拿到数据- 未处理异步请求的时序差:请求返回前数据为空,直接取值会得到undefined
- (可选)如果未在reducer中正确监听
GET_PERSON类型的action,也会导致数据未存入Redux Store
修复步骤
1. 调整Profile组件的请求调用位置与状态映射
修正后的Profile.js代码如下:
import React, { Component } from 'react' import { getPerson } from '../actions/personActions'; import * as PropTypes from 'prop-types' import { connect } from "react-redux"; class Profile extends Component { // 组件挂载后只发起一次请求 componentDidMount() { // 请替换为实际的用户id来源,比如从路由参数获取:this.props.match.params.id const userId = 1; this.props.getPerson(userId, this.props.history); } render() { // 取值前做空值兼容 const userInfo = this.props.userInfo || {}; return ( <div> <p>用户邮箱:{userInfo.email || '数据加载中...'}</p> {/* 剩余的渲染逻辑 */} </div> ) } } Profile.propTypes = { getPerson: PropTypes.func.isRequired, userInfo: PropTypes.object, errors: PropTypes.object }; // 映射Redux Store中的数据到组件Props,字段需和你reducer定义的存储路径一致 const mapStateToProps = state => ({ errors: state.errors, // 假设你在reducer中将用户数据存在state.person.userInfo下,按实际存储路径修改 userInfo: state.person.userInfo }); export default connect( mapStateToProps, { getPerson } )(Profile);
2. 确认actions.js中已正确导入action类型
请补全GET_PERSON常量的导入,避免action类型为undefined导致reducer无法监听:
// 按你实际的常量存储路径修改导入路径 import { GET_PERSON } from '../constants/actionTypes'; import axios from "axios"; export const getPerson = (id, history) => async dispatch => { try { const res = await axios.get(`http://localhost:6969/users/getUsers/${id}`); const { email } = res.data; console.log(email); // 如需存入localStorage可以在这里执行:localStorage.setItem('userInfo', JSON.stringify(res.data)) dispatch({ type: GET_PERSON, payload: res.data, }); } catch (error) { history.push("/profile"); } };
3. 确认reducer逻辑正确
请确保处理用户信息的reducer已经正确监听GET_PERSON action,并将数据存入Store,示例代码如下:
import { GET_PERSON } from '../constants/actionTypes'; const initialState = { userInfo: null } export default function personReducer(state = initialState, action) { switch (action.type) { case GET_PERSON: return { ...state, userInfo: action.payload } default: return state; } }
同时确认该reducer已经在根reducer中完成注册。
额外说明
如果你需要将数据存入localStorage,建议在actions.js请求成功后执行存储操作,不要在组件的render方法中做存储逻辑,避免因重复渲染导致多次执行存储。
内容的提问来源于stack exchange,提问作者ucoder21
相关产品推荐
相关产品推荐

