使用connect()构建React Redux表单时无法提交数据的问题求助
Hey there! Let's get your form submission working properly. I’ve picked up on a few key issues in your reducer and mapDispatchToProps setup that are stopping your form data from being added to the task list. Let’s break down what’s wrong and fix it step by step:
Key Issues Identified
- Your reducer overwrites form state on input changes: When you update one field (like name), you’re replacing the entire
tasksobject with only that field—this means you lose the existing values for age and job. - The "add" action doesn’t update the task list: Right now, your reducer only adds an ID to the
tasksobject but never actually pushes the task into thelistarray. mapDispatchToPropsfunctions don’t pass input values: Your dispatch handlers (likeName) aren’t accepting the input value as an argument, so the action never gets the data it needs. You also incorrectly included action creators inside the action objects instead of using them properly.- Form uses confusing state prop naming: You mapped
state.taskstoprops.list, which makes it harder to track which data is which.
Fixed Reducer (Reducer.js)
const initialState = { tasks: { name: "", age: "", job: "", }, list: [ { id: 0, name: "Maillard", age: 35, job: "soldier" }, ], }; export const toDoReducer = (state = initialState, action) => { switch (action.type) { case "name": return { ...state, // Preserve existing task fields while updating the name tasks: { ...state.tasks, name: action.payload }, }; case "age": return { ...state, tasks: { ...state.tasks, age: action.payload }, }; case "job": return { ...state, tasks: { ...state.tasks, job: action.payload }, }; case "clear": return { ...state, tasks: { name: "", age: "", job: "" }, }; case "add": return { ...state, // Add the current task to the list with a unique ID list: [...state.list, { ...state.tasks, id: state.list.length > 0 ? state.list[state.list.length - 1].id + 1 : 1 }], // Reset the form after successful submission tasks: { name: "", age: "", job: "" }, }; default: return { ...state }; } }; export default toDoReducer;
What Changed:
- For each input update, we use
...state.tasksto keep existing form values while overwriting the changed field. - The "add" action now creates a new
listarray by spreading the existing list and adding the currenttasksobject (with a unique ID). We also reset the form fields immediately after adding the task.
Fixed Form Component
import React from "react"; import { connect } from "react-redux"; import { setName, setAge, setJob, clearForm, addForm } from "../../redux/action"; export const Form = (props) => { return ( <div> Name <input value={props.tasks.name} onChange={(e) => props.setName(e.target.value)} /> Age <input value={props.tasks.age} onChange={(e) => props.setAge(e.target.value)} /> Profession <input value={props.tasks.job} onChange={(e) => props.setJob(e.target.value)} /> <div style={{ padding: 20 }}> <button onClick={props.clearForm}>Reset</button> <button onClick={props.addForm}>Envoyer</button> </div> </div> ); }; // Simplified mapDispatch using action creators const mapDispatchToProps = { setName, setAge, setJob, clearForm, addForm }; // Map state to props with clear naming const mapStateToProps = (state) => ({ tasks: state.tasks, taskList: state.list // Optional: use this to render the task list if needed }); export default connect(mapStateToProps, mapDispatchToProps)(Form);
What Changed:
- Renamed the mapped state prop to
tasksto match your state structure (no more confusinglistprop for form data). - Updated
mapDispatchToPropsto use your existing action creators directly—connect automatically wraps them indispatchfor you, making the code cleaner. - Fixed input handlers to pass the input value to the action creators.
Bonus: Using Action Creators Properly
If your action.js file defines creators like this (which it looks like it does), the simplified mapDispatchToProps above works perfectly:
// action.js export const setName = (value) => ({ type: "name", payload: value }); export const setAge = (value) => ({ type: "age", payload: value }); export const setJob = (value) => ({ type: "job", payload: value }); export const clearForm = () => ({ type: "clear" }); export const addForm = () => ({ type: "add" });
Now when you click "Envoyer", the form data will be added to the list array, and the form will reset automatically. You can render the task list anywhere in your app by accessing props.taskList (from mapStateToProps) and mapping over it.
内容的提问来源于stack exchange,提问作者Dryes
相关产品推荐
相关产品推荐

