Reputation: 3023
I am building an where it has few dropdowns. Here the problem is when user make selection in dropdown and if they refresh dropdown selection value reset back to default value. Instead I want to keep the value persisted so that when user make refresh it gets value from last selected dropdown value.
For that i tried using localstorage and it does save the value. But inside useEffect I try to get value and pass it to make api call it gives empty string for few times. Since the server gives me error.
Here is my code
const DispensingIncidents = (props) => {
const classes = useStyles();
const {
getFilterData,
dispensingData, // data from server side
getOverviewData,
location,
history,
getAnalysis,
clearAnalysis,
getDuration,
} = props;
const [timeSpan, setTimeSpan] = React.useState("");
const [year, setYear] = React.useState(2020);
const [tabValue, setTabValue] = React.useState(0);
const [spanData, setSpanData] = React.useState([]);
const [dataType, setDataType] = React.useState("");
const [durationLabel, setDurationLabel] = React.useState("");
const [dataTo, setDataTo] = React.useState("");
const [dataFrom, setDataFrom] = React.useState("");
// incidencesSection hide and show
const [incidencesSection, setIncidencesSection] = React.useState(false);
// handle overview select state
const [overViewSelect, setOverViewSelect] = React.useState("");
// stay selected tab on refresh
// eslint-disable-next-line
const [selectTab, setSelectTab] = React.useState(0);
const {
loading,
duration,
period,
type,
_reference,
dispensingOverviewData,
overviewDataLoading,
incidenceAnalysisData, // bottom accordion data,
incidenceAnalysisDataArray, // bottom accordion data array
analysisDataLoading,
} = dispensingData;
const { count } = dispensingOverviewData;
useEffect(() => {
history.replace({
pathname: location.pathname,
search: `?year=${year}&period=${timeSpan}&type=${dataType}&duration=${durationLabel}&overview=${overViewSelect}`,
});
setYear(year);
setTimeSpan(timeSpan);
window.localStorage.setItem(
"incidenceState",
JSON.stringify({
year,
timeSpan,
dataType,
durationLabel,
dataTo,
dataFrom,
})
);
return () => {
window.localStorage.removeItem("incidenceState");
};
// eslint-disable-next-line
}, [
year,
timeSpan,
dataType,
durationLabel,
overViewSelect,
dataTo,
dataFrom,
]);
/**
* This updates on Year given
*/
useEffect(() => {
getFilterData(year);
getDuration(year);
}, [getFilterData, year, getDuration]);
const [once, setOnce] = React.useState(0);
useEffect(() => {
if (duration !== "" && type !== "") {
if (
type !== "" &&
once === 0 &&
duration.monthly.length > 0 &&
_reference !== ""
) {
setOnce(1);
console.log("OverviewPeriod", Object.keys(period));
getOverviewData(
Object.keys(period)[3],
duration.monthly[0].period.to,
duration.monthly[0].period.from,
Object.keys(type)[0],
_reference
);
setTimeSpan(Object.keys(period)[3]);
setDataFrom(duration.monthly[0].period.from);
setDataTo(duration.monthly[0].period.to);
setDataType(Object.keys(type)[0]);
}
}
}, [duration, type]);
/**
* GET query from url search param
* @usage query.get("year")
*/
function useQuery() {
return new URLSearchParams(location.search);
}
const query = useQuery();
const time = query.get("period");
useEffect(() => {
if (time === "yearly") {
const yearlyData = duration["yearly"];
setSpanData(yearlyData);
} else if (time === "weekly") {
const weeklyData = duration["weekly"];
setSpanData(weeklyData);
} else if (time === "quarterly") {
const quarterlyData = duration["quarterly"];
setSpanData(quarterlyData);
} else if (time === "monthly") {
const monthlyData = duration["monthly"];
setSpanData(monthlyData);
} else if (time === "6 months") {
const halfYearlyData = duration["half-yearly"];
setSpanData(halfYearlyData);
}
}, [time, duration]);
/**
*
* @param {*} event
* @param {*} newValue
* on tab change
*/
// eslint-disable-next-line
const handleTabChange = (event, newValue) => {
setTabValue(newValue);
};
useEffect(() => {
if (duration !== "") {
getOverviewData(
timeSpan,
duration.monthly[0].period.to,
duration.monthly[0].period.from,
dataType,
_reference
);
}
}, [duration]);
/**
* Year change
* @param {*} event
*/
const handleYearChange = (event) => {
const v = event.target.value;
setYear(v);
setTimeSpan(query.get("period"));
getDuration(v);
};
/**
* Span change
* @param {*} event
*/
const handleSpanChange = (event) => {
const value = event.target.value;
const reValue = value === "6 months" ? "half-yearly" : value;
setTimeSpan(value);
getOverviewData(
value,
duration[reValue][0].period.to,
duration[reValue][0].period.from,
dataType,
_reference
);
setDataTo(duration[reValue][0].period.to);
setDataFrom(duration[reValue][0].period.from);
setIncidencesSection(false);
setOverViewSelect("");
};
const handleSpanTabChange = (data, i) => {
setSelectTab(i);
setDataTo(data.period.to);
setDataFrom(data.period.from);
getOverviewData(
time,
data.period.to,
data.period.from,
dataType,
_reference
);
setDurationLabel(data.label);
setOverViewSelect("");
setIncidencesSection(false);
};
const handleDataTypeChange = (event) => {
setDataType(event.target.value);
getOverviewData(time, dataTo, dataFrom, event.target.value, _reference);
setIncidencesSection(false);
setOverViewSelect("");
};
const handleOverViewClick = (data) => {
clearAnalysis();
setOverViewSelect(data);
const value = time === "6 months" ? "half_yearly" : time;
getAnalysis(data, value, dataFrom, dataTo, dataType, 1, _reference);
setIncidencesSection(true);
};
const handlePageNext = (pageNo) => {
getAnalysis(
overViewSelect,
time,
dataFrom,
dataTo,
dataType,
pageNo,
_reference
);
};
// useEffect(() => {
// const localValue = JSON.parse(
// window.localStorage.getItem("incidenceState")
// );
// console.log("localValue", localValue);
// }, []);
return (
<div className={classes.dispenseRoot}>
<Paper
elementType="div"
elevation={5}
square={true}
variant="elevation"
className={classes.topContainer}
>
<div className={classes.topContainerDiv}>
<div className={classes.topContainerLeft}>
<div className={classes.headerTextDiv}>
<p>Period</p>
</div>
<FormControl variant="outlined" className={classes.formControl}>
<Select
className={classes.containerSelect}
id="demo-simple-select-outlined"
value={timeSpan}
onChange={handleSpanChange}
>
{Object.values(period).map((span, i) => {
return (
<MenuItem key={i} value={span.toLowerCase()}>
{span.toUpperCase()}
</MenuItem>
);
})}
</Select>
</FormControl>
<FormControl variant="outlined" className={classes.formControl}>
<Select
className={classes.containerSelect}
id="demo-simple-select-outlined"
value={year}
onChange={handleYearChange}
>
<MenuItem value={2020}>2020</MenuItem>
<MenuItem value={2019}>2019</MenuItem>
<MenuItem value={2018}>2018</MenuItem>
<MenuItem value={2017}>2017</MenuItem>
</Select>
</FormControl>
<div className={classes.typeHeading}>
<p>Type</p>
</div>
<FormControl variant="outlined" className={classes.formControl}>
<Select
className={classes.containerSelect}
id="demo-simple-select-outlined"
value={dataType}
onChange={handleDataTypeChange}
>
{Object.keys(type).map((key) => {
return (
<MenuItem key={key} value={key}>
{key.toUpperCase()}
</MenuItem>
);
})}
</Select>
</FormControl>
</div>
</div>
</Paper>
<div className={classes.dispensingIncidentsTabDiv}>
<Paper square>
<Tabs
value={tabValue}
indicatorColor="primary"
textColor="primary"
onChange={handleTabChange}
variant="scrollable"
scrollButtons="on"
aria-label="scrollable auto tabs example"
>
<Tab
className={classes.dispensingTab}
label="INCIDENCES"
{...a11yProps(0)}
/>
</Tabs>
</Paper>
</div>
{incidencesSection ? (
<div className={classes.incidencesAccordionDiv}>
<IncidenceAccordion
handlePageNext={handlePageNext}
incidenceAnalysisDataArray={incidenceAnalysisDataArray}
data={incidenceAnalysisData}
title={"Incidences"}
/>
</div>
) : null}
</div>
);
};
Upvotes: 0
Views: 1906
Reputation: 167172
Every time when you call setX()
useState()
hook, try to save the value in the localStorage
. What I'd do in short is:
const [Value, setValue] = useState("");
const handleSetValue = (newValue) => {
setValue(newValue);
window.localStorage.setItem("Value", newValue);
}
And I use the handleSetValue()
instead of setValue
. And the same way, in the useEffect()
hook, I'll try to load all the values this way:
useEffect(() => {
// While loading, load the state from the localStorage.
if (window.localStorage.getItem("Value"))
setValue(window.localStorage.getItem("Value"));
}, [])
The above code will help you to persist your data from reloads.
Upvotes: 1