0

I'm building an application that needs to load a "workspace" from the database based on the slug provided in the URL. My URL structure is /app/<workspace slug>/<workspace view>. Currently there are 3 views for each workspace: Map, List and Settings. I need to get the value of the <workspace slug> from the URL in order to load the correct workspace from the database. Also I need to return an error if the workspace is not found.

I'm pretty new to React so I may not currently be following best practices.

My Routing

Currently I'm routing to each workspace view by looping through each workspace and creating a route for each of the 3 views in App.js:

renderContent() {
    return (
        <Switch>
            <Route path="/" component={NetworkMap} exact />
              {this.state.workspaces.map(function(workspace, index){ // Map View Routes
                return (
                  <Route path={"/app/" + workspace.slug + "/map"} render={(props) => <Workspace {...props} workspace={workspace} component={Map} />} />
                );
              })}
              {this.state.workspaces.map(function(workspace, index){ // List View Routes
                return (
                  <Route path={"/app/" + workspace.slug + "/list"} render={(props) => <Workspace {...props} workspace={workspace} component={List} />} />
                );
              })}
              {this.state.workspaces.map(function(workspace, index){ // Settings View Routes
                return (
                  <Route path={"/app/" + workspace.slug + "/settings"} render={(props) => <Workspace {...props} workspace={workspace} component={WorkspaceSettings} />} />
                );
              })}
            <Route component={Error} />
        </Switch>
    );
}

My Links

{props.workspaces.map(function(workspace, index){
  return (<Link key={index} to={"/app/" + workspace.slug + "/map"} className="dropdown-item cursor-pointer">{workspace.name}</Link>);
})}

My Index.js

<BrowserRouter>
    <App />
</BrowserRouter>

I've tried changing workspace.slug to :slug in the Route's path which I thought should make it appear in props but I can't seem to get it working properly:

{this.state.workspaces.map(function(workspace, index){
  return (
    <Route path={"/app/:slug/map"} render={(props) => <Workspace {...props} workspace={workspace} component={Map} />} />
  );
})}

1 Answer 1

1

match

Components rendered via the render prop will also be passed some route props, specifically, match is the one you want. From there props.match.params.slug will be the slug value you want

{this.state.workspaces.map(function(workspace, index){
  return (
    <Route
      path="/app/:slug/map"
      render={props => (
        <Workspace
          {...props}
          workspace={workspace}
          component={Map}
          slug={props.match.params.slug}
        />
      )}
    />
  );
})}

match can also be access within the component Workspace via the spread in props. If Workspace is a functional component, react-router-dom also has a useParams hook.

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for the response. Sounds like the right direction, however this is in my App.js component, and using this.props.match.params.slug gives the error TypeError: Cannot read property 'params' of undefined
Am I missing an import statement perhaps?
@Brack No, these are route props that any Route passes to anything rendered by the render prop. Mind sharing what your Router code looks like in App.js?
Eh, sorry, I guess I assumed you were using react-router-dom. What navigation are you using?
I updated the router section to include all my routing code. I am using react-router-dom import {Route, Switch} from "react-router-dom"
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.