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

使用React Hooks与Redux实现POST请求受阻,寻求技术解决方案

Hey there, let's work through the issues in your code step by step to get that POST request working and fill in the Redux integration gaps you're missing.

1. Fix the Redux dispatch setup in App.js

Right now, your addPost action isn't actually being dispatched to Redux because your connect call isn't mapping the action to your component's props. You have two clean ways to fix this:

Option A: Use useDispatch (Hooks-style, more modern)

Ditch the connect wrapper entirely and use the useDispatch hook just like you do in the Posts component:

import { useState, useDispatch } from "react";
import "./App.css";
import Posts from "./components/posts";
import { addPost } from "./store/actions/postAction";

function App() {
  const [title, setTitle] = useState("");
  const [body, setBody] = useState("");
  const dispatch = useDispatch(); // Add this line

  const handleSubmit = (event) => {
    event.preventDefault();
    const post = { title, body };
    dispatch(addPost(post)); // Wrap addPost with dispatch
    setTitle('');
    setBody('');
    alert("Post added!");
  };

  // ... rest of your component code
}

export default App; // No need for connect anymore

Option B: Use mapDispatchToProps with connect

If you prefer keeping connect, map the action to props:

// At the bottom of App.js
const mapDispatchToProps = {
  addPost
};

export default connect(null, mapDispatchToProps)(App);

// Then in handleSubmit, call props.addPost(post):
const handleSubmit = (event) => {
  event.preventDefault();
  const post = { title, body };
  props.addPost(post); // Now this will dispatch the action
  // ... rest of code
};

2. Fix the async POST request in postAction.js

Your addPost action has two critical issues:

  • You're not awaiting the axios.post call, so you'll try to access response.data before the request completes
  • The POST URL is likely incorrect (you're sending to http://localhost:8002/ instead of /posts)
  • You're wrapping the post in an extra {post} object unless your backend explicitly expects that structure

Here's the fixed version:

import axios from "axios";
import { GET_POSTS, ADD_POST, POSTS_ERROR, POSTS_LOADING } from "../types";

const url = "http://localhost:8002/";

// Add this action type if you haven't already for loading state
export const getPosts = () => async (dispatch) => {
  try {
    dispatch({ type: POSTS_LOADING }); // Set loading to true before fetch
    const response = await axios.get(`${url}posts`);
    dispatch({
      type: GET_POSTS,
      payload: response.data,
    });
  } catch (error) {
    dispatch({
      type: POSTS_ERROR,
      payload: error.message, // Store the error message instead of the full error object
    });
  }
};

export const addPost = (post) => async (dispatch) => { // Mark as async
  try {
    dispatch({ type: POSTS_LOADING });
    const response = await axios.post(`${url}posts`, post); // Fix URL and remove extra wrapping
    dispatch({
      type: ADD_POST,
      payload: response.data,
    });
  } catch (error) {
    dispatch({
      type: POSTS_ERROR,
      payload: error.message,
    });
  }
};

3. Fix state updates and initial state in postReducer.js

Your reducer is missing loading/error state fields, and the ADD_POST case is replacing the entire posts array instead of adding the new post to it. Here's the corrected reducer:

import { ADD_POST, GET_POSTS, POSTS_ERROR, POSTS_LOADING } from "../types";

// Add loading and error to initial state
const initialState = {
  posts: [],
  loading: false,
  error: null
};

const postReducer = (state = initialState, action) => {
  switch (action.type) {
    case POSTS_LOADING:
      return {
        ...state,
        loading: true,
        error: null
      };
    case GET_POSTS:
      return {
        ...state,
        posts: action.payload,
        loading: false,
        error: null
      };
    case ADD_POST:
      // Add the new post to the existing array instead of replacing it
      return {
        ...state,
        posts: [...state.posts, action.payload],
        loading: false
      };
    case POSTS_ERROR:
      return {
        ...state,
        loading: false,
        error: action.payload
      };
    default:
      return state;
  }
};

export default postReducer;

4. Fix state selector in posts.js

Double-check that your selector matches the key you used for the post reducer in your root reducer. For example, if your root reducer looks like this:

import { combineReducers } from 'redux';
import postReducer from './postReducer';

export default combineReducers({
  posts: postReducer // Key is "posts"
});

Then update your selector in Posts to:

const postsList = useSelector((state) => state.posts); // Not state.postsList

5. Quick backend check

Make sure your backend endpoint http://localhost:8002/posts accepts POST requests, and that it's configured to parse JSON request bodies (e.g., using express.json() if you're using Express.js).

Once you apply these fixes, your POST request should send data correctly, Redux will update the state with the new post, and your Posts component will display it automatically.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 03:22:36