aditya kumar
aditya kumar

Reputation: 3023

How to persist data search param in url in react js

I am working on an app which need to fetch data from api and change data on user input. Here the problem is when user first mount the page they should send a default value monthly and 2020. But if user made any changes and if they refresh page it should send user updated data. like if user selected 'half-yearly' and 2018 then on refresh it should send half-yearly and 2018. I am not sure if it is possible in reacjs or not.

I have tried doing this but it is not working it goes by monthly and 2020 every time I refresh page.

Here is my code

const DispensingIncidents = (props) => {
  const classes = useStyles();
  const {
    getFilterData,
    dispensingData,
    getPeriodList,
    getOverviewData,
    location,
    history,
  } = props;

  const [timeSpan, setTimeSpan] = React.useState("Monthly");
  const [year, setYear] = React.useState(2020);
  const [tabValue, setTabValue] = React.useState(0);
  const [spanData, setSpanData] = React.useState([]);
  const { loading, duration, period, dispensingOverviewData } = dispensingData;
  const { count } = dispensingOverviewData;

  useEffect(() => {
    getPeriodList();
  }, [getPeriodList]);

  useEffect(() => {
    history.replace({
      pathname: location.pathname,
      search: `?year=${year}&period=${timeSpan}`,
    });
    setYear(year);
    setTimeSpan(timeSpan);
    // eslint-disable-next-line
  }, [year, timeSpan]);

  useEffect(() => {
    getFilterData(year);
  }, [getFilterData, year]);

  function useQuery() {
    return new URLSearchParams(location.search);
  }
  const query = useQuery();



  // eslint-disable-next-line
  const handleTabChange = (event, newValue) => {
    setTabValue(newValue);
  };

  const handleYearChange = (event) => {
    setYear(event.target.value);
    setTimeSpan(query.get("period"));
  };

  const handleSpanChange = (event) => {
    const value = event.target.value;

    setTimeSpan(value);
  };

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

Any help would be great.

Upvotes: 5

Views: 2525

Answers (3)

t3__rry
t3__rry

Reputation: 2849

Hi you'd need one function to decode your URL params and one to encode them and sync your state's value and the URL params.

const valueFromURL = decodeYourURLParams(window.location.search)
const [valuesYouExpect, setValuesYouExpect] = useState(valueFromURL);

// or setting your state in useEffect if it's more proper

You would need to be able to pass params to your getPeriodList() function to append the params to your API call.

useEffect(() => {
   getPeriodList(decodeYourURLParams(window.location.search); // for instance
}, [getPeriodList, valuesYouExpect]);

Then whenever the user changes the value, create a new URL and push a new state to history

function updateValues(newValues) {
  const updatedValues = { ...valuesYouExpect, ...newValues };
  const { pathname, origin } = window.location;
  const newURL = `${origin}${pathname}?${encodeYourUrlParams(updatedValues)}`;

  // now change the URL
  window.history.replaceState({}, '', newURL);

  updateStateValues(updatedValues);

Now when your value are updated, history is updated and it triggers a call to the API with your params.

And also when your refresh params set in the URL get passed to your component.

Upvotes: 1

Ivan Satsiuk
Ivan Satsiuk

Reputation: 353

When you refresh the page, all data that you have in your app, e.g. state, props, redux state, etc. is gone. There are several ways to keep the data:

  • store it on the backend
  • store it in the localStorage as pointed out in the comment above
  • store it in the cookies

When you start your app (e.g. after refresh) you should check whether you have previously saved the data anywhere. Then you set it as default value in the hook

Upvotes: 2

Tomáš Hartman
Tomáš Hartman

Reputation: 49

Well, talking about refreshing the whole page, I suppose you could use localStorage, either the react-ey way like the one from useHooks or natively as explained on javascript.info.

Upvotes: 0

Related Questions