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

React组件调用Axios无请求,新闻数据无法加载问题排查

问题描述

正在为网站开发新闻栏模块,用于展示站点更新内容片段。已完成后端数据Schema、Post与Get请求路由开发,前端采用Axios处理请求、Redux管理全局状态、配置CORS。通过NewsBar组件嵌套NewsPosts组件渲染新闻内容,但目前控制台仅输出NewsPosts相关日志,未发起任何网络请求,Redux中的newsPosts为空对象,无法获取预期的新闻数据,请求排查原因。


相关代码

NewsBar组件

function useQuery() {
    return new URLSearchParams(useLocation().search);
}

const NewsBar = () => {
    const classes = useStyles();
    const query = useQuery();
    const page = query.get('page') || 1;
    const searchQuery = query.get('searchQuery');
    
    const [currentId, setCurrentId] = useState(0);

    console.log(`NewsBar: ${useLocation().search} | query=>${query}`);
    console.log(`searchquery: ${searchQuery}`);
    
    return (
        <>
        <Grow in>
            <Grid container direction={'row'}  className={classes.newsBar} justifyContent='center'>
                <Typography variant='h3'>News Bar</Typography>
                <Grid item>
                    <NewsPosts setCurrentId={setCurrentId} />
                    
                </Grid>
            </Grid>
        </Grow>
        </>
    )
}

export default NewsBar;

NewsPosts组件

const NewsPosts = ({ setCurrentId }) => {
    const { newsPosts, isLoading } = useSelector((state) => state.newsPosts);
    const classes = useStyles();

    newsPosts.map((newsPost) => {
        console.log(newsPost);
    })
    
    console.log(new Date().toISOString());
    console.log(`newsPosts array: ${typeof newsPosts} ${newsPosts}`)
    if (!newsPosts.length && !isLoading) return 'No news posts.';
 

    return (
        isLoading ? <LinearProgress /> : (
            <Grid container alignItems='stretch' spacing={3}>
                {newsPosts?.map((newsPost) => (
                    
                    <Grid key={newsPost._id} item xs={12} sm={12} md={12} lg={12}>
                        <NewsPost newsPost={newsPost} setCurrentId={setCurrentId}/>
                    </Grid>
                ))}
            </Grid>
        )
    );
};

export default NewsPosts;

控制台日志

NewsBar:  |  query=>
NewsBar.js:27 searchquery: null
NewsPosts.js:17 2022-12-01T20:36:08.958Z
NewsPosts.js:18 newsPosts array: object 

Redux Actions代码

import { START_LOADING, END_LOADING, FETCH_POST, FETCH_ALL, DELETE, CREATE } from "../constants/actionTypes";
import * as api from '../api/index.js';

//CREATE ACTIONS -> should follow the standard XMLHTTPRequest operation

export const getNewsPost = (id) => async (dispatch) => {
    try {
        console.log('actions: action getNewsPost was called');

        dispatch({ type: START_LOADING })
        const { data } = await api.fetchNewsPost(id);
        dispatch({type: FETCH_POST, payload: { newsPost: data }});
        console.log(`got post ${data}`);
    } catch (error) {
        console.log(error);
    }
};

export const getNewsPosts = (page) => async (dispatch) => {
    try {
        console.log('actions: action getNewsPosts was called');

        dispatch({ type: START_LOADING });
        const {data : {data, currentPage, numberOfPages }} = await api.fetchNewsPosts(page);

        dispatch({ type: FETCH_ALL, payload: { data, currentPage, numberOfPages }});
        dispatch({ type: END_LOADING });
    } catch (error) {
        console.log(error);
    }
};

export const createNewsPost = (newsPost, history) => async (dispatch) => {
    try {
      console.log('actions: action createNewsPosts was called');

      dispatch({ type: START_LOADING });
      const { data } = await api.createNewsPost(newsPost);
  
      dispatch({ type: CREATE, payload: data });
  
      history.push(`/newsPosts/${data._id}`);
    } catch (error) {
      console.log(error);
    }
};

export const deleteNewsPost = (id) => async (dispatch) => {
    try {
      console.log('actions: action deleteNewsPost was called');

      await await api.deletePost(id);
  
      dispatch({ type: DELETE, payload: id });
    } catch (error) {
      console.log(error);
    }
};

API配置代码

import axios from 'axios';

const API = axios.create({ baseURL: 'http://localhost:5000' });

API.interceptors.request.use((req) => {
  if (localStorage.getItem('profile')) {
    req.headers.Authorization = `Bearer ${JSON.parse(localStorage.getItem('profile')).token}`;
  }

  return req;
});

export const fetchPost = (id) => API.get(`/posts/${id}`);
export const fetchPosts = (page) => API.get(`/posts?page=${page}`);
export const fetchPostsByCreator = (name) => API.get(`/posts/creator?name=${name}`);
export const fetchPostsBySearch = (searchQuery) => API.get(`/posts/search?searchQuery=${searchQuery.search || 'none'}&tags=${searchQuery.tags}`);
export const createPost = (newPost) => API.post('/posts', newPost);
export const likePost = (id) => API.patch(`/posts/${id}/likePost`);
export const comment = (value, id) => API.post(`/posts/${id}/commentPost`, { value });
export const updatePost = (id, updatedPost) => API.patch(`/posts/${id}`, updatedPost);
export const deletePost = (id) => API.delete(`/posts/${id}`);

export const signIn = (formData) => API.post('/user/signin', formData);
export const signUp = (formData) => API.post('/user/signup', formData);

export const fetchNewsPost = (id) => API.get(`/news/${id}`);
export const fetchNewsPosts = (page) => API.get(`/news?page=${page}`);
export const createNewsPost = (newNewsPost) => API.post('/news', newNewsPost);
export const deleteNewsPost = (id) => API.delete(`/news/${id}`);

解决方案

1. 触发数据加载Action

当前代码未调用getNewsPosts Action,导致无网络请求发起。需在组件中通过useDispatch和useEffect触发请求:

修改NewsPosts组件:

import { useDispatch } from 'react-redux';
import { getNewsPosts } from '../actions/newsActions'; // 按实际路径调整
import { useEffect } from 'react';

const NewsPosts = ({ setCurrentId }) => {
    const { newsPosts, isLoading } = useSelector((state) => state.newsPosts);
    const dispatch = useDispatch();
    const classes = useStyles();

    // 组件挂载时发起请求
    useEffect(() => {
        dispatch(getNewsPosts(1)); // 可传入page参数,比如从父组件接收
    }, [dispatch]);

    // 防止非数组类型调用数组方法
    if (!Array.isArray(newsPosts)) return '数据格式异常';

    console.log(new Date().toISOString());
    console.log(`newsPosts array: ${typeof newsPosts} ${newsPosts}`)
    if (!newsPosts.length && !isLoading) return '暂无新闻内容';
 
    return (
        isLoading ? <LinearProgress /> : (
            <Grid container alignItems='stretch' spacing={3}>
                {newsPosts.map((newsPost) => (
                    <Grid key={newsPost._id} item xs={12} sm={12} md={12} lg={12}>
                        <NewsPost newsPost={newsPost} setCurrentId={setCurrentId}/>
                    </Grid>
                ))}
            </Grid>
        )
    );
};

export default NewsPosts;

或在NewsBar中触发并传递page参数:

const NewsBar = () => {
    // ... 原有代码
    const dispatch = useDispatch();

    useEffect(() => {
        dispatch(getNewsPosts(page));
    }, [dispatch, page]);

    // ... 原有return逻辑
}

2. 修正Redux初始状态

控制台显示newsPosts为对象,说明Reducer初始状态错误,需将newsPosts设为数组:

// newsReducer.js
const initialState = {
    newsPosts: [],
    isLoading: false,
    currentPage: 1,
    numberOfPages: 1
};

export default (state = initialState, action) => {
    switch (action.type) {
        case FETCH_ALL:
            return {
                ...state,
                newsPosts: action.payload.data,
                currentPage: action.payload.currentPage,
                numberOfPages: action.payload.numberOfPages
            };
        // 其他case逻辑
        default:
            return state;
    }
};

3. 修复Delete Action的API调用错误

deleteNewsPost Action存在冗余await和错误API调用:

export const deleteNewsPost = (id) => async (dispatch) => {
    try {
        console.log('actions: action deleteNewsPost was called');
        await api.deleteNewsPost(id); // 去掉多余await,调用新闻专属删除接口
        dispatch({ type: DELETE, payload: id });
    } catch (error) {
        console.log(error);
    }
};

内容的提问来源于stack exchange,提问作者Zachery Uporsky

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 14:45:48