Open In App

How to Handle Forms in Redux Applications?

Last Updated : 06 May, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Handling forms in Redux applications involves managing form data in the Redux store and synchronizing it with the UI. By centralizing the form state in the Redux store, you can easily manage form data, handle form submissions, and maintain consistency across components.

We will discuss a different approach to handle forms in Redux applications:

Steps to Create a React App and Installing required Modules

Step 1: Create a React Application

npx create-react-app <foldername>

Step 2: Move to the project folder using the following command:

cd <foldername>

Step 3: Install redux-form dependency and update package.json

npm install redux-form redux react-redux

Project Structure:

Screenshot-2024-04-06-173305

The updated Dependencies in package.json file:

"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"redux-form": "^8.3.10",
"redux": "^5.0.1",
"web-vitals": "^2.1.4"
},

Using Redux Form Library

Redux Form is a popular library for managing form state in Redux applications. It provides a set of higher-order components and Redux actions to simplify form handling. With Redux Form, you define your form fields as components and connect them to the Redux store using the `reduxForm` higher-order component. Redux Form manages form state, validation, submission, and error handling automatically.

Example: Below is an example of handling form using redux form library.

CSS
/*  App.css for UI Styling */
.form-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100vh;
}

form {
    width: 300px;
    padding: 20px;
    border: 1px solid #080707;
    border-radius: 8px;
    background-color: #eccc8d;
}

form label {
    display: block;
    margin-bottom: 8px;
    font-weight: bold;
}

form input {
    width: calc(100% - 12px);
    padding: 8px;
    margin-bottom: 16px;
    border: 1px solid #ccc;
    border-radius: 4px;
}

button[type="submit"] {
    width: 100%;
    padding: 10px;
    background-color: #007bff;
    color: #fff;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

button[type="submit"]:hover {
    background-color: #0056b3;
}

.data-display {
    margin-top: 20px;
}

.data-display div {
    margin-bottom: 8px;
}
JavaScript
// src/App.js
import MyForm from "./components/MyForm";

function App() {
    return (
        <>
            <MyForm />
        </>
    );
}

export default App;
JavaScript
// src/store.js
import { createStore } from 'redux';
import rootReducer from './reducers';

const store = createStore(rootReducer);

export default store;
JavaScript
// src/components/MyForm.js
import React, { useState } from "react";
import { Field, reduxForm } from "redux-form";
import '../App.css';

const MyForm = (props) => {
    const { handleSubmit } = props;
    const [data, setData] = useState({});

    const onSubmit = (values) => {
        // Handle form submission
        setData(values);
        console.log(values);
    };

    return (
        <>
            <div className="form-container">
                <form onSubmit={handleSubmit(onSubmit)}>
                    <div>
                        <label htmlFor="name">Name</label>
                        <Field name="name" component="input" type="text" />
                        <label htmlFor="name">Password</label>
                        <Field name="password" component="input" type="password" />
                    </div>
                    <button type="submit">Submit</button>
                    <div>Name:{data.name}</div>
                    <div>Password:{data.password}</div>
                </form>

            </div>
        </>
    );
};

export default reduxForm({
    form: "myForm", // A unique identifier for this form
})(MyForm);
JavaScript
// src/reducers/index.js
import { combineReducers } from 'redux';
import { reducer as formReducer } from 'redux-form';

const rootReducer = combineReducers({
  form: formReducer
});

export default rootReducer;

Start your application using the following command:

npm start

Output:

red-ezgifcom-video-to-gif-converter

Using Custom Redux Actions and Reducers

In this approach, you manually define Redux actions and reducers to handle form state. You create actions to update form fields, reducers to manage form state in the Redux store, and selectors to retrieve form data from the store. This approach gives you more control over form handling but requires more manual setup compared to using Redux Form.

Example: Below is an example of handling form using custom redux actions and reducers.

CSS
/*  App.css */
/* Container for the form */
.container {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100vh;
}

/* Form styling */
form {
    width: 300px;
    padding: 20px;
    border: 1px solid #ccc;
    border-radius: 8px;
    background-color: #83e964;
}

form label {
    display: block;
    margin-bottom: 8px;
    font-weight: bold;
}

form input[type="text"] {
    width: calc(100% - 12px);
    padding: 8px;
    margin-bottom: 16px;
    border: 1px solid #ccc;
    border-radius: 4px;
}

/* Submit button styling */
button[type="submit"] {
    width: 100%;
    padding: 10px;
    background-color: #007bff;
    color: #fff;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

button[type="submit"]:hover {
    background-color: #0056b3;
}

/* Submitted data display styling */
.submitted-data {
    margin-top: 20px;
}

.submitted-data h2 {
    margin-bottom: 8px;
}
JavaScript
// index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { Provider } from 'react-redux';
import store from './store';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <Provider store={store}>
        <App />
    </Provider>
);

reportWebVitals();
JavaScript
// App.js
import MyForm from "./components/MyForm";

function App() {
    return (
        <>
            <MyForm />
        </>
    );
}

export default App;
JavaScript
// src/components/MyForm.js
import React, { useState } from 'react';
import { useDispatch } from 'react-redux';
import { updateFormField, submitForm } from '../actions';
import '../App.css';

const MyForm = () => {
    const dispatch = useDispatch();
    const [formData, setFormData] = useState({ name: '' });
    const [submittedData, setSubmittedData] = useState(null);

    const handleChange = (e) => {
        const { name, value } = e.target;
        setFormData({ ...formData, [name]: value });
        dispatch(updateFormField(name, value));
    };

    const handleSubmit = (e) => {
        e.preventDefault();
        dispatch(submitForm(formData));
        setSubmittedData(formData); // Store submitted data in state
        console.log(formData);
        setFormData({ name: '' }); // Clear form after submission
    };

    return (
        <div className='container'>
            <form onSubmit={handleSubmit}>
                <div>
                    <label htmlFor="name">Name</label>
                    <input
                        type="text"
                        id="name"
                        name="name"
                        value={formData.name}
                        onChange={handleChange}
                    />
                </div>
                <button type="submit">Submit</button>
                {submittedData && (
                    <div>
                        <h2>Submitted Data:</h2>
                        <p>Name: {submittedData.name}</p>
                    </div>
                )}
            </form>

        </div>
    );
};

export default MyForm;
JavaScript
// src/store.js
import { createStore, combineReducers } from 'redux';
import formReducer from './reducers/formReducer';

const rootReducer = combineReducers({
    form: formReducer
});

const store = createStore(rootReducer);

export default store;
JavaScript
// src/actions/index.js
export const actionTypes = {
    UPDATE_FORM_FIELD: 'UPDATE_FORM_FIELD',
    SUBMIT_FORM: 'SUBMIT_FORM'
};

export const updateFormField = (field, value) => ({
    type: actionTypes.UPDATE_FORM_FIELD,
    payload: { field, value }
});

export const submitForm = (formData) => ({
    type: actionTypes.SUBMIT_FORM,
    payload: formData
});
JavaScript
// src/reducers/formReducer.js
import { actionTypes } from '../actions';

const initialState = {
    formData: {
        name: ''
    }
};

const formReducer = (state = initialState, action) => {
    switch (action.type) {
        case actionTypes.UPDATE_FORM_FIELD:
            return {
                ...state,
                formData: {
                    ...state.formData,
                    [action.payload.field]: action.payload.value
                }
            };
        // Handle other form actions here

        default:
            return state;
    }
};

export default formReducer;

Output:

grg-ezgifcom-video-to-gif-converter



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads