Home > Software design >  Any data passed through useLocation gives null after reloading
Any data passed through useLocation gives null after reloading

Time:08-29

In a table I'm populating certain list of data which has their respective id. When clicking on the links, redirected to a new page where I'm getting the id of the record for further use, but, at times gets null data. What could be best solution prevent data to be null. Please refer to the code

Here list of data is passed to component

const newCompData = [
    {
      id: 1,
      comp: "McDonalds",
      feedback: "Best Food Chain",
      name: "Mike John",
      est: "YYYY/MM",
      store: "Burger Store"
    },
    {
      id: 2,
      comp: "KFC",
      feedback: "Best Chicken Products",
      store: "Chicken Food",
      name: "Steve Williams",
      est: "YYYY/MM"
    },
    {
      id: 3,
      comp: "Dominos",
      feedback: "Best Pizza Store",
      store: "Pizza Store",
      name: "Mark Rays",
      est: "YYYY/MM"
    },
    {
      id: 4,
      comp: "Star Bucks",
      feedback: "Best Coffee Store",
      store: "Coffee Store",
      name: "Patrick Right",
      est: "YYYY/MM"
    },
    {
      id: 5,
      comp: "Burger King",
      feedback: "Best Burgers",
      store: "Burger Store",
      name: "Williams Wills",
      est: "YYYY/MM"
    },
    {
      id: 6,
      comp: "Lays",
      feedback: "Best Chips Factory",
      store: "Chips Store",
      name: "Sam Andrews",
      est: "YYYY/MM"
    }
  ];

  const [dataAll, setDataAll] = useState([]);

  useEffect(() => {
    const newData = newCompData?.map((data) => {
      return [
        { id: data.id },
        data.comp,
        data.store,
        data.name,
        data.est,
        data.feedback
      ];
    });

    setDataAll(newData);
  }, []);

  return (
    <div className="App">
      <Table newData={dataAll} />
    </div>
  );
};

Table.js

const Table = ({ newData }) => {
  console.log("PROPS", newData);
  useEffect(() => {
    setGridData({
      data: newData,
      page_info: {
        total_pages: 5,
        current_page: 1
      }
    });
  }, [newData]);

  let GridConfig = {};

  GridConfig = TableConfig;

  const [gridConfigData, setGridConfigData] = useState(GridConfig);
  const [gridData, setGridData] = useState(newData);

  return (
    <>
      <Grid GridConfig={gridConfigData} GridData={gridData} />
    </>
  );
};

In the above Table component the data is mapped, which is then passed to Grid component

Grid.js

import { useNavigate } from "react-router";

const Grid = (props) => {
  let colConfig = props.GridConfig.column_config;
  let gridData = props.GridData?.data;

  const navigate = useNavigate();

 // Here the id is passed to Test component
  const clickCallback = (id) => {
    const state = { id };
    navigate("/test", {
      state
    });
  };

  return (
    <div className="table-responsive pt-3">
      <table className="table table-bordered table-striped" width="100%">
        <thead>
          <tr>
            {colConfig.map((d, key) => {
              return (
                <th key={key} colSpan={d.col_span} className={d.title_class}>
                  {d.title}
                </th>
              );
            })}
          </tr>
        </thead>
        <tbody>
          {gridData &&
            gridData.map((rowData, rIndex) => {
              return (
                <tr
                  key={`tr_${rowData[0].id}`}
                  className={rowData[0].row_properties}
                >
                  {rowData.slice(0).map((colData, cIndex) => {
                    return (
                      <td
                        key={`td_${rIndex}_${cIndex}`}
                        className={colConfig[cIndex].data_col_class}
                      >
                        {colConfig[cIndex].data_type === "text" &&
                          colConfig[cIndex].cell_click_callback && (
                            <div>
                              <a onClick={() => clickCallback(rowData[0].id)}>
                                {" "}
                                {colData}{" "}
                              </a>
                            </div>
                          )}
                        {colConfig[cIndex].data_type === "text" &&
                          !colConfig[cIndex].cell_click_callback && (
                            <div>{colData}</div>
                          )}
                      </td>
                    );
                  })}
                </tr>
              );
            })}
        </tbody>
      </table>
    </div>
  );
};

export default Grid;

Test.js

import { useLocation } from "react-router-dom";

const Test = () => {
  const location = useLocation();

  const newId = location.state?.id

  console.log("Location", location);
  return (
    <>
      <h2>Test Page</h2>
      <p>ID here: {newId}</p>
    </>
  );
};

export default Test;

Here the id at first is received without any issue but, gives null on reloading or coming second times to the page. How could this null of id be prevented?

Please refer Codesandbox link --> https://codesandbox.io/s/elated-varahamihira-xpjtdb

CodePudding user response:

as Konrad said, if you want to have the id on reload you should persist it in localStorage for example. Or use this approach of passing the id as a param in the URL, here is how:

change the Test component's path in App.js to:

<Route path="/test/:id" element={<Test />} />

then change the clickCallback to:

const clickCallback = (id) => {
    navigate(`/test/${id}`);
  };

and the last change is to use useParams in Test.js, you can read more on this hook here:

const params = useParams();
const newId = params.id;

you can see the full changes in this codesandbox

CodePudding user response:

See the link brother useLocation hook keeps states even on hard refresh. These link will help you sure. Or you may use useParams() hooks or save id into localStorage. Then, Extract and used it.

  • Related