Lucas AllenGo to homepage

How To Get A Parameter From A URL In React

Retrieving query parameters (also known as search parameters) from a URL in a React application is essentially the same as any JavaScript application.

We will briefly explore how this is done and then jump into some examples with the React-dependent NPM package React Router that make this process more streamlined.

Getting Started

First, let’s boot up a small React app using create-react-app.

yarn create react-app search-params-example
cd search-params-example

First, let's remove what we don’t need from App.js and make a few changes to App.css. Now we should have the following:

/* src/App.css */
.App {
  background-color: #282c34;
  min-height: 100vh;
  text-align: center;
}

.App-header {
  color: white;
  display: flex;
  flex-direction: column;
  font-size: calc(10px + 2vmin);
  padding-top: 1rem;
}
// src/App.js
import "./App.css";

function App() {
  return (
    <div className="App">
      <header className="App-header">URL Search Params Example</header>
    </div>
  );
}

export default App;

Defining the App

We need a way to update the URLs search parameters to properly explore the different ways we can read the URL’s parameters. Let’s build a simple form that lets us submit a user rating for a movie without wasting too much time or making something completely arbitrary.

Let’s also suppose that we want to prepopulate this form via the search parameters from the URL. Perhaps we want users to be able to share links with other people with a suggested rating for a specific movie. Don’t think about it too much.

Our app will be an extremely simple form that can be pre-populated from the URL’s query or search parameters. Here is our simple form:

// src/MovieForm.js
function MovieForm() {
  return (
    <form className="App-form">
      <div className="App-form-field">
        <label>Title</label>
        <input name="title" type="text" />
      </div>

      <div className="App-form-field">
        <label>Rating</label>
        <input name="rating" type="range" min="1" max="10" />
      </div>

      <button type="submit">Save</button>
    </form>
  );
}

export default MovieForm;

Go ahead and add this component to the App.js file and add the following CSS to App.css:

.App-form {
  align-items: flex-start;
  background-color: white;
  border-radius: 3px;
  display: flex;
  flex-direction: column;
  margin: 2rem auto 0;
  max-width: 20rem;
  padding: 1rem;
}

.App-form button {
  margin: 0 auto;
  padding: 0.5rem 1rem;
}

.App-form-field {
  display: grid;
  grid-template-columns: 5rem 1fr;
  margin-bottom: 1rem;
}

.App-form-field label {
  margin-right: 0.2rem;
}

Extracting the Parameters from the URL Before immediately reaching for React Router to solve our problem, let’s see how we can get the search parameters with vanilla JavaScript. If nothing else, this will at least help us understand how other packages and libraries might do the same “under the hood”.

JavaScript has a useful constructor called URLSearchParams which provides us with an interface to extract search parameters from a string of URL parameters. Since we can get this URL parameter string from the global window object, we can get the data we need on the mount thanks to React’s useEffect.

const [rating, setRating] = useState("1");
const [title, setTitle] = useState(" ");
const [ready, setReady] = useState(false);

useEffect(() => {
  const urlSearchString = window.location.search;
  const params = new URLSearchParams(urlSearchString);

  setTitle(params.get("title"));
  setRating(params.get("rating"));
  setReady(true);
}, []);

if (!ready) return;

I invite you to flex your React skills and see how you can use these states to update the JSX this component returns. For more on what other tools the URLSearchParams constructor returns, check out the page MDN has on this topic here.

Using React Router

First, let’s install React Router.

yarn add react-router-dom

Then update index.js so that we can use the package’s library in our App (and ultimately in our MovieForm component). It should look something like this:

// src/index.js
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import { createBrowserRouter, RouterProvider } from "react-router-dom";

const router = createBrowserRouter([
  {
    path: "/",
    element: <App />,
  },
]);

const root = ReactDOM.createRoot(document.getElementById("root"));

root.render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
);

Finally, we’re able to hop back into our MovieForm component. React Router has many useful hooks and tools to aid us with routing in our React applications, but we’re most interested in the useSearchParams hook. It uses the very same URLSearchParams internally, so this will only relieve us of a few minor lines of code at first.

Try it yourself before reading the code below and see if you get the same result.

// src/MovieForm.js
function MovieForm( ) {
 const [rating, setRating] = useState('1');
 const [title, setTitle] = useState(' ');
 const [ready, setReady] = useState(false);

 const [searchParams,] = useSearchParams( );

  useEffect(( ) => {
    if (ready) return;

    setTitle(searchParams.get('title'));
    setRating(searchParams.get('rating'));
    setReady(true);
  }, [ready, searchParams]);

...

Because of the RouterProvider, we no longer have to extract the search parameters manually, letting the useSearchParams hook do some of that work.

Now when we submit the form, the page does a full refresh. Before, this didn’t stop us, but if we had other interactions on the page or needed to do some other work in the onSubmit event, this could pose a problem.

Luckily, useSearchParams also provides us with a setter method that makes it simple to update the search params.

Please take the time to see how it’s done on the React Router Page.

Conclusion

Now you know how to extract the search parameters (or query parameters) from a URL – both inside and outside of the React context.

Take note that in most applications, if the data is small, it may be a better idea to take more advantage of modern routing packages and put the data in the URL path instead of in query parameters. In situations where you might have a mixture of the two, then using a package like React Router is even more advisable.

If you have a small one-off case where you need to handle these parameters in your app, read up more on how you can use the URLSearchParams constructor. Good luck!