Map failing to refresh

Having some trouble with the map function as it's not updating my select box with the new selected value. The issue occurs within a material UI dialog that appears when viewing a file. I notice that the values get updated only after closing and reopening the modal, but they don't refresh otherwise. Any assistance on this matter would be highly appreciated.

import React, { useEffect, useState } from 'react';
import Grid from '@material-ui/core/Grid';
import Paper from '@material-ui/core/Paper';
import InputLabel from '@material-ui/core/InputLabel';
import FormControl from '@material-ui/core/FormControl';
import Select from '@material-ui/core/Select';
import { makeStyles } from '@material-ui/core/styles';
import MenuItem from '@material-ui/core/MenuItem';

import filter from '../../../constants/filter-options';
 
export default function KeywordFilter(props) {
    
    const [selectedFilter, setFilter] = useState(props.selectedFilter);
    
    const [filterOptions, setFilterOptions] = useState(filter);

    const useStyles = makeStyles(theme => ({
        root: {
            flexGrow: 1
        },
        paper: {
            padding: theme.spacing(2),
            textAlign: 'center',
            color: theme.palette.text.primary,
        },
        modal: {
            height: '80vh',
            width: '40vw',
            maxWidth: '40vw'
        }
    }));

    const classes = useStyles();

    const handleChange = (event, keyword) => {
        var temp =  selectedFilter;
        
        temp[keyword] = event.target.value;
        console.log("TEMP: ", temp)
        console.log("keywordList: ", keywordList)

        props.onFilterChange(temp);
        setFilter(temp)
        setFilterOptions(filter)
    };

    const keywordList = Object.keys(filterOptions)

    
    return (


        <div key={keywordList}>
            <h4 style={{textAlign:'center'}}>Filters: </h4>
            <Grid container spacing={3}>
                {keywordList.map((keyword) => {
                    return (
                        <Grid item xs={6}>
                            {console.log("selectedFilter: ", selectedFilter)}
                            <Paper className={classes.paper}>
                            {keyword}:&nbsp;<FormControl className={classes.formControl}>
                                                <Select
                                                    key={keyword}
                                                    labelId="demo-simple-select-label"
                                                    id="demo-simple-select"
                                                    value={selectedFilter[keyword] ? selectedFilter[keyword] : "None"}
                                                    onChange={(e) => handleChange(e, keyword)}
                                                >
                                                    {filterOptions[keyword].map(element => <MenuItem value={element}>{element}</MenuItem>)}
                                                </Select>
                                            </FormControl>
                            </Paper>
                        </Grid>
                    )}
                )}
            </Grid>
        </div>
    ); 
}

The filter module resembles the structure below:

const filter = 
{
    Schedule : ["None", "Monthly", "Quarterly", "Semi-Annually",  "Annually"],    
    Chemical : ["None", "Copper", "Phosphorus"],
    Color : ["None", "Black", "Blue"]
}

export default filter;

Answer №1

After some troubleshooting, I discovered that directly modifying the state was causing a multitude of issues. By making some adjustments to the handleChange function and eliminating unnecessary code, I was able to resolve the issue:

import React, { useEffect, useState } from 'react';
import Grid from '@material-ui/core/Grid';
import Paper from '@material-ui/core/Paper';
import FormControl from '@material-ui/core/FormControl';
import Select from '@material-ui/core/Select';
import { makeStyles } from '@material-ui/core/styles';
import MenuItem from '@material-ui/core/MenuItem';

import filter from '../../../constants/filter-options';
 
export default function KeywordFilter(props) {

    const useStyles = makeStyles(theme => ({
        root: {
            flexGrow: 1
        },
        paper: {
            padding: theme.spacing(2),
            textAlign: 'center',
            color: theme.palette.text.primary,
        },
        modal: {
            height: '80vh',
            width: '40vw',
            maxWidth: '40vw'
        }
    }));

    const classes = useStyles();

    const handleChange = (event, keyword) => {
        
        // Make a deep copy of selected filters to prevent direct state modification
        const target = JSON.parse(JSON.stringify(props.selectedFilter)) 
        // Set new value to add
        const source = { [keyword]: event.target.value};
        // Merge the two objects (this also updates the target)
        const results = Object.assign(target, source)
        // Update the state
        props.onFilterChange(results)
    };

    return (
        <>
            <h4 style={{textAlign:'center'}}>Filters: </h4>
            <Grid container spacing={3}>
                {Object.keys(filter).map((keyword) => {
                    return (
                        <Grid item xs={6}>
                            <Paper className={classes.paper}>
                            {keyword}:&nbsp;<FormControl className={classes.formControl}>
                                                <Select
                                                    key={keyword}
                                                    labelId="demo-simple-select-label"
                                                    id="demo-simple-select"
                                                    value={props.selectedFilter[keyword] ? props.selectedFilter[keyword] : "None"}
                                                    onChange={(e) => handleChange(e, keyword)}
                                                >
                                                    {filter[keyword].map(element => <MenuItem value={element}>{element}</MenuItem>)}
                                                </Select>
                                            </FormControl>
                            </Paper>
                        </Grid>
                    )}
                )}
            </Grid>
        </>
    ); 
}

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

Tips for preventing access to user media when integrating Redux

I've been facing an issue while working with navigator.mediaDevices.getUserMedia(mediaConstraints) in conjunction with Redux. I am struggling to find a solution to stop the media stream. I attempted to halt the media stream within the reducer and act ...

Increase the object name in localStorage to save information entered in input fields

For testing purposes only - do not use for production. I am experimenting with storing data from 3 different input fields (text and numbers) in localStorage. My goal is to have the values increment every time the form is submitted. However, I am encounte ...

Troubleshoot: Unable to Change CSS on Click Using Javascript/jQuery

Having trouble creating three different buttons that toggle between various images using the CSS display property? Check out my code on https://jsfiddle.net/agt559e8/. function USradarChange1() { //document.getElementById("usradar1").src="weather/curr ...

Collaborate on sessions across Next.js and React applications

I manage a scenario where I have a Next application utilizing Keycloak for authentication via NextAuth, and another React application also secured by Keycloak using the official keycloak libraries (keycloak-js and react-keycloak/web), both residing within ...

What is the best way to retrieve recently inserted data using Sequelize in PostgreSql?

Is there a way to retrieve updated table values after adding a user to the "WOD" table without making an additional query? Currently, when I add a third user to my WOD table, I can only return the first two users because I am unable to access the updated ...

Issue arises when fastify/websocket is being used and an argument of type '{ websocket: boolean; }' is not compatible or able to be assigned to a parameter

I am facing an issue with my new project that involves fastify and Typescript. The error I am encountering is as follows: Argument of type '{ websocket: boolean; }' is not assignable to parameter of type 'RouteShorthandOptions ...ts(2345) B ...

The id in the router prop of the Next.js app does not correspond with the React

I recently developed a Next.js app with an App Router, and within the app folder, I created a page called `app/about/page.jsx`. My goal is to incorporate the React Chrono library for creating timelines on this specific page. To achieve this, I established ...

What is the reason for Bower consistently choosing to download the Angular version 1.5.9-build.5086+sha...?

Struggling to manage my front end dependencies using bower.json. No matter how I specify the version of Angular in bower, a different version is downloaded every time. The issue is that many functionalities in my code rely on previous versions of Angular, ...

Ensure the header remains fixed when scrolling in an HTML page with Bootstrap

I created the following code. However, when I scroll down the table, the header disappears from view. I would like the header to always remain at the top, even when scrolling. Despite searching Google multiple times and trying various solutions, I have no ...

Unlocking Node.js packages within React JS is a seamless process

Currently, I am developing a React Serverless App with AWS. I am looking for ways to incorporate a Node JS specific package into the React JS code without requiring Node JS on the backend. One package that I need access to is font-list, which enables list ...

Tips for displaying a tooltip or title on a cell in PrimeReact Data table

I have a challenge with displaying a data table using prime react data table. I would like to incorporate tooltips or titles similar to the example shown in the image below, that appear when hovering over a cell. After reviewing the Column component, I co ...

What steps can you take to ensure that a recreated React component retains its state?

Within this sandbox demo, there is an example that may seem contrived but effectively makes a point. Upon clicking the "Add column" button, it should add a new column. However, it only works once and fails on subsequent attempts. Upon inspection of the lo ...

Prevent the immediate response to the initial state change in React when a second change is made, especially when

Scenario: Working with a state called usersData that updates whenever the user applies filters to their data. The process of querying and updating this large object can be time-consuming. When a user triggers the filter change change1, it takes around 5 s ...

Looking for a solution to dynamically fill a list in JQuery with data from a JSON file. Any suggestions for troubleshooting?

Currently, I am utilizing a JSON file to fetch Quiz questions. In my approach, each question is being stored in an array as an object. The structure of the question object includes 'text' (the actual question), 'choices' (an array of po ...

Conceal a row in a table using knockout's style binding functionality

Is it possible to bind the display style of a table row using knockout.js with a viewmodel property? I need to utilize this binding in order to toggle the visibility of the table row based on other properties within my viewmodel. Here is an example of HTM ...

How can CSS filters be applied to an SVG image within a tag?

One way to apply basic CSS filters is by using the following code: <img src="..." style={{ filter: "blur(5px) ..." }} /> Alternatively, you can use this code snippet: <img src="..." style="filter: blur(5px)" ...

How to Include ".00" When Calculating Dollar Amount Totals Using Math.js

When working with my MongoDB and Node backend, I need to calculate total dollar amounts and send that information to the front end. It's important to note that I am only displaying totals and not making any changes to the values themselves. To ensure ...

How can I retrieve the offset top of a td element in relation to its parent tr element?

Here is some sample dummy HTML code: <table> <body> <tr> <td id="cell" style="height: 1000px; width: 200px;"></td> </tr> </body> </table> I am looking to attach a click event ...

Is it necessary for me to replicate this function? - jQuery

I have developed a function that creates a transparent information overlay on a current div for a mobile web app. Context: I am using jQTouch, which means I have separate divs instead of loading individual pages anew. $(document).ready(function() { ...

Dealing with Oversized Images in Jcrop: Tips and Tricks

Utilizing Jcrop for cropping images, everything runs smoothly with small images. However, when I attempt to use large images like 2080x2080 or 1600x1600, it takes up the entire screen and cannot be controlled by CSS properties such as width and height in t ...