首页 > 解决方案 > React 不会更新下拉选项,并且与 console.log 语句不匹配

问题描述

我似乎无法弄清楚为什么我的模态没有正确更新。我尝试了 useEffect、useMemo、useCallback 的不同变化,我得到了相同的最终结果(不同)。发生的情况是在Device激活模式时选择 。应该从该选项中提取值,并遍历对象列表以找到匹配的 id。找到后,该数据将传递给setDevices. 出现了两个问题。(第一个 .map() 调用正常工作,第二个 .map() 不返回任何内容,即使使用过度杀伤的三元语句)

问题 1:如果我对 ID 进行硬编码。然后 modalData 被更新。如果我使用 e.target.value 并在控制台记录它,控制台会显示正确的 ID,但如果我允许 React 进行比较,React 总是返回 false。

问题 2:如果devices肯定填充并再次显示在控制台中。Devices.map 不起作用,也不会显示选项。

它几乎就像控制台和 React 是 2 个不同的实体。我在那里有日志语句,所以我知道何时呈现整个页面或仅呈现项目。我认为这两种解决方案都可以,要么重新渲染模态,要么更好地重新渲染更改后的输出。

我也使用 react-redux,但我认为为 1 个屏幕上使用的模式进行调度和操作有点过分。不过,这可能是我的最后一个解决方案。

import React, { useEffect, useState } from "react";

function TCOAddModal({makes, display}){

    const displayModal = display ? {"display":"block"} :
        {"display":"none"} 

    function handleMakeNameChange(e){
        console.log('ID ', e.target.value)
        let printers = makes.filter(printer => printer.id === e.target.value)
        setModalData(prev=>{
            return({
                ...prev,
                devices:printers
            })
        })
        
    }  
    
    function handleBlur(e){
        handleMakeNameChange(e)
    }
    
    const [modalData, setModalData] = useState({
        device:'',
        devices:[],
        deviceQuantity:'',
        monthlyLease:0,
        monthlyMonoPages : '',
        monthlyColorPages: '',
        totalMonthlyPages:'',
        baseVolumeMono: '',
        baseVolumeColor: '',
        baseRateMono: '',
        baseRateColor: '',
        currentMonoCpp: '',
        currentColorCpp: ''
    })

    
    function handleModalData(e){
        const { name, value } = e.target
        console.log("modal data!", name)
        setModalData((prevValue) => {
            switch (name) {
                case "tcoDevice-makeName":
                    return {
                        ...prevValue,
                        TCOMakeName: value
                    };
                case "deviceQuantity":
                    return {
                        ...prevValue,
                        deviceQuantity: value
                    };
                case "monthlyLease":
                    return {
                        ...prevValue,
                        monthlyLeasePayment: value
                    }
                case "monthlyMonoPages":
                    return {
                        ...prevValue,
                        monthlyMonoPages: value
                    }
                case "monthlyColorPages":
                    return {
                        ...prevValue,
                        monthlyColorPages: value,
                    }
                case "totalMonthlyPages":
                    return {
                        ...prevValue,
                        totalMonthlyPages: value
                    }
                case "baseVolumeMono":
                    return {
                        ...prevValue,
                        baseVolueMono: value
                    }
                case "baseRateMono":
                    return {
                        ...prevValue,
                        baseRateMono: value
                    }
                case "baseVolumeColor":
                    return {
                        ...prevValue,
                        baseVolumeColor: value
                    }
                case "baseRateColor":
                    return {
                        ...prevValue,
                        baseRateColor: value
                    }
                case "currentMonoCpp":
                    return {
                        ...prevValue,
                        currentMonoCpp: value
                    }
                case "currentColorCpp":
                    return {
                        ...prevValue,
                        currentColor: value
                    }
                default:
                    console.log('Error setting value ')
            }
        })
    }
     


    useEffect(()=>{
        console.log('TCOAddModaleffect: ')

    }, [makes, modalData.devices])
    console.log('Mounted in main body of TCOADDModal?')

    retutn(


...
                    <div className="cell medium-8 medium-offset-2">
                        <select id="tcoDevice-makeName" onBlur ={handleBlur} onChange={handleMakeNameChange} name="TCOMakeName">
                            <option defaultValue="-1"></option>
                            { makes && makes.map((printer, ix) => <option key={ix} value={printer.id}>{printer.name}</option>)}
                        </select>
                    </div>
                </div>
                <div className="grid-x align-middle modal-row">
                    <div className="cell medium-10 medium-offset-2">Device</div>
                    <div className="cell medium-8 medium-offset-2">
                        <select id="tcoDevice-shortName">
                            {modalData.devices && modalData.devices.length > 0 && modalData.devices.map(
                            device=>(
                                <option key={device.id}>{device.short_model}</option>
                            )
                        ) }</select>
                    </div>
                </div>
...



export default TCOAddModal

标签: javascriptreactjsmodal-dialogstate

解决方案


呃,我修好了。简单错误。过滤器返回一个列表,而不是单个对象。从列表中拉出第一项。我也错误地访问了该属性。
let printers = makes.filter(printer => printer.id === e.target.value)
应该是
let printers = makes.filter(printer => printer.id == e.target.value)[0]
or
let printers = makes.filter(printer => printer.id === Number(e.target.value))[0]
==============================*
另外,JSlint 让我失望了,Expected '===' and instead saw '==' 在我的情况下,==是必需的,因为e.target.value它是一个字符串。
JSLint 期望 '===' 而看到 '=='


推荐阅读