1

I am passing props to the same component in two different ways.

Once by Route path:-

<Route path="/CreateProfile/:title" exact component={ProfileForm} />

Another by Link as:

<Table.Cell><Link to={{  // it will land to the same component ProfileForm
pathname:  "/EditProfile",
props: {
profile : profile,
title: "Edit Profile" 
}
}} >Edit Profile</Link></Table.Cell>

In my ProfileForm, I tried to read props as:-

useEffect(() => {

  if(props.match.params.title){ // it gives no error. 
    setTitle(props.match.params.title);
  }else if(props.location.props.title){ // gives error .props.title undefiened 
    setTitle(props.location.props.title);
  }
  // if(props.match.params.profile){
  //   setProfile(props.location.state.profile)
  // }
  if(props.location.props.profile){
    setProfile(props.location.props.profile)
    console.log("profile: "+props.location.props.profile)
  }
}

else if(props.location.props.title) gives an error when it comes from the Router. It is expected because I set props by Link. I noticed props.match.params.title never gives any error whether it is set or not. So I wish to pass props by the match from Link so that both Route and Link works properly. Is it possible to pass props by match? Or how do I solve this issue?

Afia
  • 683
  • 5
  • 17
masiboo
  • 4,537
  • 9
  • 75
  • 136
  • Are you sure about the Link fragment? Your link to prop has `pathname: "/EditProfile"`, but your Route has `/CreateProfile` pathname! – Hamed Navabian Mar 01 '20 at 18:46
  • I have also another Route as ``. So both /CreateProfile and //EditProfile points to the same component. Once I create a new profile and another time I allow to edit an existing profile. – masiboo Mar 01 '20 at 18:50
  • Would you please provide a better example of your code? Because you can pass the challenge with different ways. – Hamed Navabian Mar 01 '20 at 19:24

1 Answers1

0

You can pass data via the pathname (URL), i.e. via url match or query parameters, or via route state.

Link to-object

An object that can have any of the following properties:

  • pathname: A string representing the path to link to.
  • search: A string representation of query parameters.
  • hash: A hash to put in the URL, e.g. #a-hash.
  • state: State to persist to the location.

You clearly have your route setup for the pathname variant with a route param of title.

"/CreateProfile/:title"

You should simply construct your link to have the correct title value built into it.

<Link to={{ pathname: "/CreateProfile/<some title value>" }} >
  Create Profile
</Link>

From here you need only access the route's match.params.title as you've correctly done.

Now, in the case of the edit profile route, "/EditProfile" there is, OFC, no route match param (and no query parameters), so the correct way is to use route state.

<Link
  to={{
    pathname: "/EditProfile",
    state: {
      profile,
      title: 'Edit Title',
    },
  }}
>
  Edit Profile
</Link>

And correctly access route state from the history object

useEffect(() => {
  const { history, match } = props;

  if (match.params.title) { 
    setTitle(match.params.title);
  } else if (history.location.state.title){
    setTitle(history.location.state.title);
  }

  if (history.location.state.profile) {
    setProfile(history.location.state.profile)
    console.log("profile: ", history.location.state.profile)
  }
}

Word of advice about the route state however, the object path isn't always guaranteed to exist (i.e. be defined) from props.history.location to the ultimate value you are accessing, so guard are necessary to prevent "access blah of undefined" errors.

 // state may not be defined depending on which route the app took to get to the page
history.location.state && history.location.state.title
Drew Reese
  • 165,259
  • 14
  • 153
  • 181