3
votes

I have filters for my application. I'd like to do shallow routing, and add the queries to the URL when a user changes the filters at the same time update my application state. But this seems like I'm maintaining two states. Are there any best practices for this? as i'd like my url to match application state

2

2 Answers

3
votes

Derive your app state from the url. That means that you need to change the url, and the app will re-render -> derive the new state from the url.

// somePage.jsx

import { useRouter } from 'next/router';
import { useState, useEffect } from 'react';

const somePage = () => {
  const router = useRouter();
  const [myState, setMyState] = useState({ page: 1 });
  useEffect(() => {
    setState({ page: query.page });
  }, [router.query.page]);

  return (
    <div>
      {JSON.stringify(myState)}
      {[1, 2, 3, 4, 5].map(page => (
        <Link href={`?page=${page}`} key={page}>
          <a>page {page}</a>
        </Link>
      ))}
    </div>
  );
};

export default somePage;

0
votes

You could extract this logic to a custom hook:

import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';

export const useQueryState = (initialState = {}) => {
  const router = useRouter();
  const [state, setState] = useState(initialState);

  useEffect(() => {
    setState(router.query);
  }, [router.query]);

  const setQueryParams = (query = {}) => {
    router.push({ pathname: router.pathname, query }, undefined, {
      shallow: true,
    });
  };

  return [state, setQueryParams];
};