0

I have a React App with several Components, in separate Files.

Each Component is nested under the Root, of course.
I have BrowserRouter at the Root-level

function App() {

  return (
    <div className="app">
      <BrowserRouter>
        <Routes>
          <Route path="/product" element={<Home />} />

          <Route path="/program" element={<Program subject={SubjectSelector.TEST_SUBJECT} program={ProgramSelector.TEST_PROGRAM} />} />

          <Route path="/purchase" element={<Purchase />} />
        </Routes>
      </BrowserRouter>
    </div>
  );
}

As you can see, the /program Route Renders the <Program> Component with some Props.

I want to Route to this <Program> Component after clicking a button in my Apps' Header Navigation.

Here's my Question:

How do I Navigate to this Component when a Button is pressed AND pass in Props?

I'm hoping to avoid something like Context that I'd need to wrap around the Root Component, since that would be a lot of unnecessary data available throughout all my Components. But I need the ability to set Props and Navigate to a Component from another upon a Button Click.

I have looked around the internet for a solution, but haven't seen anything beyond the below.

I'm aware of the history.push() and history.location options. BUT, none of these allow me to pass Props.

I believe location has a state Field, but I don't believe this will populate my Props (correct me if I'm mistaken).

I effectively want to do something like:

...
  const goToProgram = (programName: string) => {
    // ... Something that allows me to Render a Component like the below
    <Program subject={SubjectSelector.FITNESS} program={programName} />
  }

 return (
   <h2 onClick={() => goToProgram(ProgramSelector.SOME_PROGRAM)} >Go To Program</h2>
 );
...

\

NOTE:

I see this Post, but it doesn't allow Props on a Component. I am asking to pass data WITH Props

For example:

<Program subject={SubjectSelector.TEST_SUBJECT} program={ProgramSelector.TEST_PROGRAM} />

I wish to handle this explicitly, with Props defined on the Component.
Then, I want to Navigate to this Component, populating these explicit Properties.

useNavigate and useLocation works, as mentioned in the above linked Post with answer section of "Pass Route State".

BUT, when I defined my BrowserRouter Routes, I give some value to the Props (e.g. <Program subject={....}.../>, so the Props exist. And if I use useLocation to extract the passed State (which is NOT via Props), I'll need to name it something different than the Props, leading to some ugly code (and never actually doing what I wanted in the first place, populating the Props themselves).

For example:

function Program( {subject, program}: {subject: SubjectSelector, program: ProgramSelector} ) {

  const { state: { sub, prog } = {} } = useLocation();
  if( sub != null ) subject = sub;
  if( prog != null ) program = prog;

  ...
}
Beasted1010
  • 111
  • 4
  • 1
    You cannot pass `props` directly. It is not possible. You will need to pass the data through the location (path, query params, or location.state). The route for that location will read that data and render the component with the correct props. For example your location could be `/program/fitness/workout` and you can have a route `/program/:subject/:program` with an element that serves as a wrapper around your existing `Program` component, using `const { subject, program } = useParams()` and returning ``. – Linda Paiste Dec 30 '22 at 18:27
  • 1
    To navigate (v5): ``const history = useHistory(); const handleClick = () => { history.push(`/program/${SubjectSelector.TEST_SUBJECT}/${ProgramSelector.SOME_PROGRAM}`); }`` – Linda Paiste Dec 30 '22 at 18:35
  • 1
    Props are passed from parent component to child component, *when they are rendered*, not when navigation actions are effected. Passing data from one "page" to another "page" is ***not*** the same thing as passing props. Data is passed in several way as the marked duplicate explains. – Drew Reese Dec 30 '22 at 22:14
  • 1
    This is actually great. I was going to refactor to use URL Path later anyways. Implemented it now and verified it works. Thank you. And thank you, Drew, for the rationale behind why this isn't possible. I'm still new to React, but that makes a lot of sense. Appreciate the help. – Beasted1010 Dec 31 '22 at 00:20

0 Answers0