React表单提交报错:Actions不可包含未定义的type属性
Hey there! Let's dig into this login problem you're hitting. Since you've confirmed your Django API is working, we can focus squarely on the React/Redux side of things—starting with that Login.js file you suspect is the culprit.
First, let's format the code snippet you shared for clarity:
const Login = (props) => { if (props.isAuthenticated) { return ( <Redirect to='/'/> ) } return ( <div className="login-page"> <FormHome {...props}...
Since your code cuts off at the <FormHome> component, here are the most likely issues to check, along with actionable fixes:
1. Missing Form Submission & API Request Logic
It looks like you're passing props to FormHome, but if there's no handler for form submission (e.g., when the user clicks "Login"), your app never actually sends a request to the Django API.
Here's how to add that logic properly:
import { connect } from 'react-redux'; import { loginUser } from '../redux/actions/authActions'; // Import your login action import { Redirect } from 'react-router-dom'; const Login = (props) => { if (props.isAuthenticated) { return <Redirect to='/' />; } // Handle form submission (pass this to FormHome) const handleLogin = async (userData) => { try { // Dispatch the Redux action to send login request to Django await props.loginUser(userData); // If successful, isAuthenticated will update, triggering the Redirect } catch (err) { // Catch and display errors (e.g., invalid credentials) console.error('Login failed:', err.response?.data || err.message); } }; return ( <div className="login-page"> {/* Pass the submission handler to FormHome */} <FormHome onSubmit={handleLogin} {...props} /> </div> ); }; // Map Redux state to component props const mapStateToProps = (state) => ({ isAuthenticated: state.auth.isAuthenticated, // Match your Redux state structure }); // Map Redux actions to component props const mapDispatchToProps = { loginUser, }; export default connect(mapStateToProps, mapDispatchToProps)(Login);
2. Redux State Sync Issues
Even if you send the API request, your isAuthenticated prop might not update if your Redux reducer isn't handling the login action correctly. Here's a sample auth reducer to ensure state updates:
const initialState = { isAuthenticated: false, user: null, error: null, }; const authReducer = (state = initialState, action) => { switch (action.type) { case 'LOGIN_SUCCESS': return { ...state, isAuthenticated: true, user: action.payload, error: null, }; case 'LOGIN_FAILURE': return { ...state, isAuthenticated: false, error: action.payload, }; default: return state; } }; export default authReducer;
3. Django CSRF Token Handling
Django requires a CSRF token for POST requests, which is a super common gotcha. Add this to your API setup (e.g., in an Axios config file) to automatically include the token:
import axios from 'axios'; import Cookies from 'js-cookie'; // Install with `npm install js-cookie` // Configure Axios to use Django's CSRF token axios.defaults.xsrfCookieName = 'csrftoken'; axios.defaults.xsrfHeaderName = 'X-CSRFToken'; axios.defaults.withCredentials = true;
Then, your login action can use this configured Axios to send the request:
export const loginUser = (userData) => async (dispatch) => { try { const response = await axios.post('/api/auth/login/', userData); dispatch({ type: 'LOGIN_SUCCESS', payload: response.data }); } catch (error) { dispatch({ type: 'LOGIN_FAILURE', payload: error.response.data }); throw error; // Let the component catch the error } };
4. Quick Debugging Steps
- Check your browser's Network Tab to see if the login request is being sent. Look for:
- Correct API endpoint URL
- 200/201 status code (success) or 403/401 (CSRF/credential issues)
- Verify your Django API allows cross-origin requests if React is running on a different port (use the
django-cors-headerspackage) - Double-check that your Redux store is properly configured with the auth reducer
内容的提问来源于stack exchange,提问作者cclloyd

