Home > Enterprise >  useParams() is emtpy when component loads
useParams() is emtpy when component loads

Time:06-07

I am using react with the following packages:

    "babel-eslint": "10.0.3",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-redux": "^7.2.4",
    "react-router-dom": "^6.3.0",
    "react-scripts": "3.2.0",
    "redux": "^4.1.1",
    "redux-thunk": "^2.3.0",
    "web-vitals": "^1.0.1",
    "web3": "^1.6.1",
    "web3-eth-contract": "^1.5.2"

My App.js looks like the following:

import React, { useEffect, useState, useRef } from "react";
import { useDispatch, useSelector } from "react-redux";
import { connect } from "./redux/blockchain/blockchainActions";
import { Routes, Route, useParams } from "react-router-dom";

function App() {
  const dispatch = useDispatch();
  const blockchain = useSelector((state) => state.blockchain);
  const identifierUrl = useParams();

  const getData = () => {
    console.log("identifierUrl: "   JSON.stringify(identifierUrl));
    const isEmpty = Object.keys(identifierUrl).length === 0;

    if (!isEmpty) {
      alert("Url Parameter exist");
    }
  };

  useEffect(() => {
    getData();
  }, [blockchain.account]);

  return (
    <>
      <h1 className="text-3xl font-bold underline">Welcome to the App</h1>
      <div>
        {blockchain.account === "" ||
        blockchain.smartContract === null ||
        Object.keys(identifierUrl).length === 0 ? (
          <div>
            <p
              style={{
                textAlign: "center"
              }}
            >
              Connect to the network
            </p>
            <button
              
              onClick={(e) => {
                e.preventDefault();
                dispatch(connect());
                getData();
              }}
            >
              <svg
                
                xmlns="http://www.w3.org/2000/svg"
                viewBox="0 0 20 20"
              >
                <path d="M13 8V2H7v6H2l8 8 8-8h-5zM0 18h20v2H0v-2z" />
              </svg>
              <span>CONNECT</span>
            </button>
            {blockchain.errorMsg !== "" ? (
              <>
                <p
                  style={{
                    textAlign: "center"
                  }}
                >
                  {blockchain.errorMsg}
                </p>
              </>
            ) : null}
          </div>
        ) : (
          <div>
            <p>Logged in</p>
          </div>
        )}
      </div>
    </>
  );
}

export default App;

When pressing the connect button I do not get the url paramter.

Like for the url https://z9usm7.csb.app/test123, I should get back test123, but I get back {}.

I also created a codesandbox to recreate the error:

https://codesandbox.io/s/hungry-hodgkin-z9usm7?file=/src/App.js:0-2160

Basically I want to get the url-parameters when the react-component loads.

Any suggestions what I am doing wrong?

CodePudding user response:

The problem is that you're trying to "grab" the params without the routes definition be in place.

The steps to make it work would be, in the App

<Routes>
 <Route path="/:id" element={<ChildThatWillReadTheParam />} />
</Routes>

Then create a child component and put the logic there: (note that here I named it ChildThatWillReadTheParam)

function ChildThatWillReadTheParam() {
  const dispatch = useDispatch();
  const blockchain = useSelector((state) => state.blockchain);
  const { id } = useParams();

  ...

  return (
    <>
      ...your JSX
    </>
  );
}

export default ChildThatWillReadTheParam;

alternatively you could create the routes definition in the index.js and wouldn't be necessary to create the ChildThatWillReadTheParam.

  • Related