【问题标题】:Map not re-rendering地图不重新渲染
【发布时间】:2020-11-20 20:48:01
【问题描述】:

我正在尝试使用地图功能,但它不会使用更新的选定值重新呈现我的选择框。 过滤器位于查看文件时弹出的材质 ui 对话框中。当我关闭模式并重新打开它时,这些值将更新,但如果我不关闭窗口,则不会更新。任何帮助将不胜感激。

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>
    ); 
}

过滤器文件如下所示:

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

export default filter;

【问题讨论】:

  • 确保selectedFilter[keyword] 确实发生了变化。
  • temp[keyword] = event.target.value; 正在改变当前状态(以及扩展的道具),它是an anti-pattern。事实上,这是您面临的问题的根源,因为只是一个引用的对象永远不会改变,因此任何 setFilter 都会被 React 忽略。
  • 这能回答你的问题吗? React Hooks useState() with Object
  • 是的,感谢您的所有帮助。事实证明我是在直接修改状态,这会产生很多问题。以下更改解决了该问题
  • const handleChange = (event, keyword) => {` //深拷贝选中的过滤器,避免直接改变状态 const target = JSON.parse(JSON.stringify(props.selectedFilter)) //set添加新值 const source = { [keyword]: event.target.value}; //合并两个对象(这也会更新目标) const results = Object.assign(target, source) //更新状态 props.onFilterChange(results) };

标签: javascript reactjs material-ui react-functional-component


【解决方案1】:

事实证明,我是在直接修改状态,这会产生很多问题。对 handleChange 函数的以下更改并删除了不必要的代码解决了该问题:

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) => {
        
        //deep copy selected filters to avoid directly changing state
        const target = JSON.parse(JSON.stringify(props.selectedFilter)) 
        //set new value to add
        const source = { [keyword]: event.target.value};
        //merge the 2 objects (this will update target aswell)
        const results = Object.assign(target, source)
        //update 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>
        </>
    ); 
}

【讨论】:

    猜你喜欢
    • 2022-08-12
    • 2021-04-06
    • 1970-01-01
    • 2019-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-02
    相关资源
    最近更新 更多