To write an action creator for submitting a form asynchronously in Redux, use Redux Thunk. Here's a concise example:
1. Install Redux Thunk
Ensure Redux Thunk is set up in your store.
2. Define the Async Action Creator
Example:
export const submitForm = (formData) => async (dispatch) => {
dispatch({ type: 'SUBMIT_FORM_START' }); // Indicate start
try {
const response = await fetch('/api/submit', {
method: 'POST',
body: JSON.stringify(formData),
headers: { 'Content-Type': 'application/json' },
});
const data = await response.json();
dispatch({ type: 'SUBMIT_FORM_SUCCESS', payload: data }); // Success
} catch (error) {
dispatch({ type: 'SUBMIT_FORM_FAILURE', payload: error.message }); // Error
}
};
3. Handle Actions in Reducer
Example:
const initialState = {
loading: false,
success: false,
error: null,
};
const formReducer = (state = initialState, action) => {
switch (action.type) {
case 'SUBMIT_FORM_START':
return { ...state, loading: true, success: false, error: null };
case 'SUBMIT_FORM_SUCCESS':
return { ...state, loading: false, success: true };
case 'SUBMIT_FORM_FAILURE':
return { ...state, loading: false, error: action.payload };
default:
return state;
}
};
export default formReducer;
4. Dispatch in Component
Example:
import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { submitForm } from './actions';
const FormComponent = () => {
const dispatch = useDispatch();
const { loading, success, error } = useSelector((state) => state.form);
const [formData, setFormData] = useState({});
const handleSubmit = (e) => {
e.preventDefault();
dispatch(submitForm(formData));
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
/>
<button type="submit" disabled={loading}>
{loading ? 'Submitting...' : 'Submit'}
</button>
{error && <p>{error}</p>}
{success && <p>Form submitted successfully!</p>}
</form>
);
};
export default FormComponent;