React with REDUX is refreshing the entire state following the update action

For the past day, I've been working on resolving a bug that has been plaguing me.

Everything was functioning perfectly before the update action. I made sure to log all the states before executing the update action.

However, after creating a model, the update action led to this result when I checked the console logs.

I couldn't understand why the dataGrid was throwing an error even though I had specified all the ids in the DataGrid component.

Uncaught Error: MUI: The data grid component requires all rows to have a unique `id` property.

This is a snippet of my code: Models Reducer:

import * as actionTypes from 'constants/actionTypes';

export default (models = [], action) => {
    switch (action.type) {
        case actionTypes.FETCH_MODELS:
            return action.payload.result;
        case actionTypes.CREATE:
            return [...models, action.payload.result];
        case actionTypes.UPDATE:
            return models.map((model) => (model.model_id === action.payload.result.model_id ? action.payload.result : model));
        case actionTypes.DELETE:
            return models.filter((model) => model.model_id !== action.payload);
        default:
            return models;
    }
};

In my model component:

import * as actionTypes from 'constants/actionTypes';

export default (models = [], action) => {
    switch (action.type) {
        case actionTypes.FETCH_MODELS:
            return action.payload.result;
        case actionTypes.CREATE:
            return [...models, action.payload.result];
        case actionTypes.UPDATE:
            return models.map((model) => (model.model_id === action.payload.result.model_id ? action.payload.result : model));
        case actionTypes.DELETE:
            return models.filter((model) => model.model_id !== action.payload);
        default:
            return models;
    }
};

My ModelForm:

<Formik
            enableReinitialize={true}
            initialValues={modelData}
            validationSchema={Yup.object().shape({
                model_code: Yup.string(4).min(4, 'Minimum value is 4.').max(50, 'Maximum value is 4.').required('Model code is required'),
                model_description: Yup.string().max(200, 'Maximum value is 200.'),
                model_status: Yup.string().min(5).max(10, 'Maximum value is 10.')
            })}
            onSubmit={async (values, { setErrors, setStatus, setSubmitting }) => {
                try {
                    if (scriptedRef.current) {
                        if (currentId === 0) {
                            // , name: user?.result?.name
                            dispatch(createModel({ ...values }, setFormVisible));
                        } else {
                            dispatch(updateModel(currentId, { ...values }, setFormVisible));
                        }
                        setStatus({ success: true });
                        setSubmitting(false);
                    }
                } catch (err) {
                    console.error(err);
                    if (scriptedRef.current) {
                        setStatus({ success: false });
                        setErrors({ submit: err.message });
                        setSubmitting(false);
                    }
                }
            }}
        >
            {({ errors, handleBlur, handleChange, handleSubmit, isSubmitting, touched, resetForm, values }) => (
                <form noValidate onSubmit={handleSubmit}>
                    <Grid container spacing={1}>
                        <Grid item lg={4} md={4} sm={12}>
                            <JTextField
                                label="Model"
                                name="model_code"
                                value={values.model_code}
                                onBlur={handleBlur}
                                onChange={handleChange}
                                touched={touched}
                                errors={errors}
                            />
                        </Grid>
                    </Grid>
                    <Grid container spacing={1} sx={{ mt: 1 }}>
                        <Grid item lg={4} md={4} sm={12}>
                            <JTextField
                                label="Description"
                                name="model_description"
                                value={values.model_description}
                                onBlur={handleBlur}
                                onChange={handleChange}
                                touched={touched}
                                type="multiline"
                                rows={4}
                                errors={errors}
                            />
                        </Grid>
                    </Grid>
                    {currentId ? (
                        <Grid container spacing={1} sx={{ mt: 1 }}>
                            <Grid item lg={4} md={4} sm={12}>
                                <JSelect
                                    labelId="model_status"
                                    id="model_status"
                                    name="model_status"
                                    value={values.model_status}
                                    label="Status"
                                    onBlur={handleBlur}
                                    onChange={handleChange}
                                    errors={errors}
                                >
                                    <MenuItem value="ACTIVE">ACTIVE</MenuItem>
                                    <MenuItem value="INACTIVE">INACTIVE</MenuItem>
                                </JSelect>
                            </Grid>
                        </Grid>
                    ) : (
                        ''
                    )}
                    <Box sx={{ mt: 2 }}>
                        <ButtonGroup variant="contained" aria-label="outlined button group">
                            <Button size="small" disabled={isSubmitting} type="submit">
                                Save
                            </Button>
                            <Button size="small" onClick={resetForm}>
                                Cancel
                            </Button>
                            {currentId ? (
                                <Button size="small" color="secondary" onClick={handleDelete}>
                                    Delete
                                </Button>
                            ) : (
                                ''
                            )}
                        </ButtonGroup>
                    </Box>
                </form>
            )}
        </Formik>

Why are products, parts, or other states being updated as well? I only intended to update the model create action.

Please review this video for more details:

I am looking for assistance in solving this bug. Apart from this issue, my CRUD template works smoothly.

Answer №1

Update: After discovering that in Redux, actions must always be unique to prevent multiple reducers from being triggered with the same action name, I have made updates to my action types. Now they are:

// AUTHENTICATION ACTIONS
export const AUTH = 'AUTH';
export const LOGOUT = 'LOGOUT';

// MODEL ACTIONS
export const FETCH_MODELS = 'FETCH_MODELS';
export const CREATE_MODEL = 'CREATE_MODEL';
export const UPDATE_MODEL = 'UPDATE_MODEL';
export const DELETE_MODEL = 'DELETE_MODEL';

// PRODUCTS ACTIONS
export const FETCH_PRODUCTS = 'FETCH_PRODUCTS';
export const CREATE_PRODUCT = 'CREATE_PRODUCT';
export const UPDATE_PRODUCT = 'UPDATE_PRODUCT';
export const DELETE_PRODUCT = 'DELETE_PRODUCT';

// ASSEMBLY ACTIONS
export const FETCH_ASSEMBLY = 'FETCH_ASSEMBLY';
export const CREATE_ASSEMBLY = 'CREATE_ASSEMBLY';
export const UPDATE_ASSEMBLY = 'UPDATE_ASSEMBLY';
export const DELETE_ASSEMBLY = 'DELETE_ASSEMBLY';

// PARTS ACTIONS
export const FETCH_PARTS = 'FETCH_PARTS';
export const CREATE_PART = 'CREATE_PART';
export const UPDATE_PART = 'UPDATE_PART';
export const DELETE_PART = 'DELETE_PART';

The reducers have been updated as follows:

import * as actionTypes from 'constants/actionTypes';

export default (models = [], action) => {
    switch (action.type) {
        case actionTypes.FETCH_MODELS:
            return action.payload.result;
        case actionTypes.CREATE_MODEL:
            return [...models, action.payload.result];
        case actionTypes.UPDATE_MODEL:
            console.log(models);
            return models.map((model) => (model.model_id === action.payload.result.model_id ? action.payload.result : model));
        case actionTypes.DELETE_MODEL:
            return models.filter((model) => model.model_id !== action.payload);
        default:
            return models;
    }
};

And the actions now look like this:

import * as actionTypes from 'constants/actionTypes';
import * as api from 'api/index.js';
import Swal from 'sweetalert2';

export const getModels = () => async (dispatch) => {
    try {
        const { data } = await api.fetchModels();
        dispatch({ type: actionTypes.FETCH_MODELS, payload: data });
    } catch (error) {
        console.log(error);
        Swal.fire('Error!', 'Something went wrong', 'error');
    }
};

export const createModel = (model, setFormVisible) => async (dispatch) => {
    try {
        const { data } = await api.createModel(model);

        dispatch({ type: actionTypes.CREATE_MODEL, payload: data });
        setFormVisible(false);

        Swal.fire('Success!', 'Model has been added successfully', 'success');
    } catch (error) {
        console.log(error);
        Swal.fire('Error!', 'Something went wrong', 'error');
    }
};

export const updateModel = (id, model, setFormVisible) => async (dispatch) => {
    try {
        const { data } = await api.updateModel(id, model);

        dispatch({ type: actionTypes.UPDATE_MODEL, payload: data });
        setFormVisible(false);
        Swal.fire('Success!', 'Model updated successfully', 'success');
    } catch (error) {
        console.log(error);
        Swal.fire('Error!', 'Something went wrong', 'error');
    }
};

export const deleteModel = (id) => async (dispatch) => {
    try {
        await await api.deleteModel(id);

        dispatch({ type: actionTypes.DELETE_MODEL, payload: id });
        Swal.fire('Success!', 'Model deleted successfully', 'success');
    } catch (error) {
        console.log(error);
        Swal.fire('Error!', 'Something went wrong', 'error');
    }
};

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Firestore in a Next.js app keeps attempting to start emulators even though it is already running

Does anyone have experience dealing with issues related to Firebase and its emulators? I keep encountering the following error during hot reload: FirebaseError: Firestore has already been started and its settings can no longer be changed. You can only mo ...

Preventing the occurrence of [ { "description": null } ] in PostgreSQL with a React application running on http://localhost:3000

While working on my localhost project at port 3000 in the Pern Todo List, I encountered a bug. When I type something and click "Add" using a POST request from my React app, the data should be added successfully. However, when I use Postman to make a GET re ...

What causes the re-rendering when setting the same value?

https://i.stack.imgur.com/LWvlR.png What is causing the excessive re-renders in this function component? I understand that function components are checked with the Object.is method and only re-render if the result is false. So why is this error happening ...

The ReactJS form fails to show any updates upon submission

Here is the code snippet I have been working on: const [messages, setMessages] = useState(messagesList); const [addMessage, setAddMessage] = useState({ messageSent: '', }); const addMessageChange = (event) => { event.preventD ...

Exploring the process of assigning custom images to individual items within arrays in React JS

Within my Json file, I have an array that details the materials of various foods. When displaying these on my recipe page, each item of material should have a corresponding image. However, with numerous food items and materials, implementing this purely le ...

Ways to determine if a web application is utilizing React

Is it possible to detect if a web application is utilizing ReactJS through the developer console when the JavaScript code has been minified? ...

The Axios frontend appears to have difficulty sending request parameters to the backend server

One of the challenges I encountered while working on my frontend with React was setting up a hook to make HTTP requests to fetch data for display. useEffect(() => { const options = { method: "GET", url: `http://localhost:8080/a ...

Unable to retrieve data from a localhost server to a different one

I have both a Webpack server for React (located at localhost:3000) and an Express server (found at localhost:4000). I followed the instructions to set up a proxy in my package.json file but it's still not working. Additionally, I tried setting headers ...

Can delayed validation be implemented for a control in react-form-hook?

One challenge I am facing is implementing a custom validation for an Input field with the mode set to "onChange". The custom validation involves checking if the user input text is present in an array of strings. However, there is concern that as the array ...

Unable to completely conceal the borders of Material UI Cards

Despite my efforts to blend the card with the background, I am still struggling with the tiny exposed corners. I've spent hours searching for a solution, but nothing seems to work. I've tried various methods such as adjusting the border radius in ...

"Alert: Jest has detected that an update to MyComponent in a test was not properly enclosed in an act() function, even though there was no actual update being made. Please

Here's a super straightforward test I've put together: it('renders', () => { const { toJSON } = render( <MockedProvider> <MyComponent /> </MockedProvider> ) expect(toJSON()).toMatc ...

Error encountered: TypeError: __webpack_require__.t is not a function - Issue appears only on live server, while localhost runs without any problem

I set up an e-commerce site that runs smoothly on localhost. However, when I deploy it to a live server, an error appears. Interestingly, the error disappears after reloading the page. Here is the code snippet: import React, { useEffect, useState } from & ...

How can we prevent Material-UI and Redux-form from re-rendering when an option is clicked in the select input?

I am facing an issue with rendering options dynamically. Whenever I click on the select or the options, the component re-renders and changes the options. As a result, I need to click twice to select an option in the dropdown. This re-rendering is happening ...

"Embracing Micro-frontends: Building dynamic web applications using a variety of frontend

I am currently facing a software architecture dilemma. My extensive monolithic web application is built using PHP and backbone js, but I am eager to integrate a new front-end framework like react/vue. The question arises about the best approach to tackle t ...

The node version you are currently using is not supported by create-react

Trying to set up a fresh ReactJS application using create-react-app on Ubuntu 18.10, I encountered an issue. Upon running create-react-app myapp, I received the following message: Note: the project was bootstrapped with an old unsupported version of t ...

Personalizing Material-UI's select component: A step-by-step guide

Desired Outcome: https://i.stack.imgur.com/khNHn.png https://i.stack.imgur.com/dQzVz.png Progress So Far: https://i.stack.imgur.com/CUixn.png Struggling to Position SVG Icon Next to Text: https://i.stack.imgur.com/4GFtA.png Issue with Black Line Whe ...

Retrieve specific information using the identifier from the URL parameters during server-side rendering

I am trying to fetch data with a parameter from the URL using Nextjs. However, I am facing an issue where the parameter value is undefined. Here is the code snippet: const Room = () => { let fetchData; let roomId; const getID = () => { con ...

When refreshing a page in Next.js, the loading indicator does not properly turn off

I'm currently working on my portfolio using next.js and I have implemented a 'loading' state to prevent displaying partially loaded gallery images. The 'loading' state should turn off (set to 0) once all the photos are fully loaded ...

What causes loss of focus in a React input element when it is nested inside a component?

When I have an input element connected to the React Context API, updating the value onChange works fine when the element is not nested within a component. However, if I render a different component just under the input that returns another input field conn ...

Changing the Position of HTML Scripts in React

I am facing an issue where I need to relocate an external script within a specific section of my page. However, I am unable to access the CSS attributes associated with this item. It seems that it is displayed as an iFrame, making it difficult to modify th ...