I have a bit of a complicated application where I'm making a chart based on the user input values. They pick a start date, and end date, and another parameter. When that extra parameter is filled, it renders the chart. The problem is when the user needs to edit the dates, in react-datepicker
, the start date and end date chosen are updated individually, so it updates the start date and resets the end date to null before the user has chosen an end date, causing the app to error out. I need to figure out how to rework the state updating, so the user has the opportunity to pick an end date when editing the dates before the chart re-renders.
Parent component:
export const OutagePanel: FC<propTypes> = (props) => {
const [parameters, setParameters] = useState({
startDate: null,
endDate: null,
unit: 'None'
})
const handleDateChange = (range) => {
const [startDate, endDate] = range;
setParameters( (prevState) => ({
...prevState,
startDate: startDate,
endDate: endDate
}))
}
const handleUnitChange = (value) => {
setParameters( (prevState) => ({
...prevState,
unit: value
}))
}
return (
<Flex>
<Flex>
<Box>Date Range:</Box>
<Box>
<DatePicker
className={styles.datepicker}
placeholderText="Click to select"
selected={parameters.startDate}
startDate={parameters.startDate}
endDate={parameters.endDate}
onChange={handleDateChange}
showMonthDropdown
showYearDropdown
dropdownMode="select"
minDate={new Date(2000, 0, 1)}
maxDate={new Date(2021, 0, 5)}
todayButton="Today"
selectsRange
/>
</Box>
</Flex>
<GeneratorUnitSelect handleUnitChange={handleUnitChange} />
{parameters.unit != 'None' && <OutageHistoryChart parameters={parameters}></OutageHistoryChart>}
</Flex>
)
}
As seen above, when parameters.unit != 'None'
it will show the OutageHistoryChart
component. So after it first successfully creates and displays a chart, when a user goes back to edit the dates, upon first click in the date picker, it will update the state to something like this:
parameters = {
startDate: <user's new date>,
endDate: null,
unit: 'Unit 1'
}
Since the updated state still contains a valid value in parameters.unit
it passes my test in the return statement and tries to re-render the chart. I know I could add an additional test parameters.endDate != null
before showing the chart and that is likely to fix it, however, it seems like I should be able to use a useEffect
here. This is what I have tried, but the useEffect
gets skipped upon editing the date range and it again fails to render the chart due to the end date missing.
export const OutagePanel: FC<propTypes> = (props) => {
const [parameters, setParameters] = useState({
startDate: null,
endDate: null,
unit: 'None'
})
const [showChart, setShowChart] = useState(false)
const handleDateChange = (range) => {
const [startDate, endDate] = range;
setParameters( (prevState) => ({
...prevState,
startDate: startDate,
endDate: endDate
}))
}
useEffect(() => {
if (parameters.unit != 'None' && parameters.endDate != null) {
setShowChart(true)
} else (
setShowChart(false)
)
}, [parameters.startDate, parameters.endDate, parameters.unit])
//more stuff
Then I changed it to this in the return statement:
{showChart && <OutageHistoryChart parameters={parameters}></OutageHistoryChart>}
Is this a case where a useEffect
is not a valid solution or am I just implementing it wrong? It just seems messy to do checking like parameter.unit != 'None' && parameter.endDate != null
in my return statement.