I cannot seem to figure out why my modal is not updating correctly. I've tried different vairation of useEffect, useMemo, useCallback and I get the same end results (differently). Whats happening is when the Device
is selected when the modal is activated. The value should be pulled from that option and a list of objects is iterated over to find the matching id. Once found, the data for that is passed to setDevices
. Two problems are occuring. ( The 1st .map() call works correctly, the 2nd .map() does not return anything, even with the overkill ternary statement)
Problem 1: If I hard code an ID. Then modalData is updated. If I use e.target.value, and console log it, the console displays the correct ID but if I allow React to do the comparison, React always returns false.
Problem 2:
If devices
are definitely populated and again, displaying in the console. Devices.map does not work and will not display the options.
It almost like the console and React are 2 different entities. I have the log statements there so I know when the whole page is render or just the item. Both solutions I think would be ok, either re-rendering the modal or better would be only re-reindering the changed output.
I also use react-redux but I think its a bit overkill to make a dispatch and action for a modal thats used on 1 screen. This might be my last solution though.
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