React Router Pass Param an Component

74
const rootEl = document.getElementById('root');

ReactDOM.render(
    <BrowserRouter>
        <Switch>
            <Route exact path="/">
                <MasterPage />
            </Route>
            <Route exact path="/details/:id" >
                <DetailsPage />
            </Route>
        </Switch>
    </BrowserRouter>,
    rootEl
);

Ich versuche, auf die ID in der DetailsPage-Komponente zuzugreifen, aber es ist nicht zugänglich. Ich habe es versucht

<DetailsPage foo={this.props}/>

Parameter an die DetailsPage zu übergeben, aber vergebens.

export default class DetailsPage extends Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
            <div className="page">
            <Header />
            <div id="mainContentContainer" >

            </div>
            </div>
    );
    }
}

Haben Sie also eine Idee, wie Sie die ID an die Detailseite weitergeben können?

Mudit Tuli
quelle

Antworten:

91

Wenn Sie Requisiten an eine Komponente innerhalb einer Route übergeben möchten, verwenden Sie am einfachsten Folgendes render:

<Route exact path="/details/:id" render={(props) => <DetailsPage globalStore={globalStore} {...props} /> } />

Sie können auf die Requisiten im folgenden zugreifen DetailPage:

this.props.match
this.props.globalStore

Das {...props}wird benötigt, um die Requisiten der Originalroute zu passieren, sonst gelangen Sie nur this.props.globalStorein die DetailPage.

Sieg
quelle
1
Aber warum sollte es nicht so funktionieren, wie ich es in der Frage angegeben habe?
Mudit Tuli
3
Erstens war Ihr Code falsch. Das Platzieren einer Komponente in einer Route wie <Route exact path="/details/:id" ><DetailsPage /></Route>war nicht dasselbe wie <Route exact path="/details/:id" component={DetailsPage} />. Ihr Code wurde DetailsPageauch dann gerendert , wenn Sie '/' besucht haben. Zweitens, als Sie geschrieben haben <DetailsPage foo={this.props}/>, thisverwiesen null. Deshalb hat es nicht funktioniert.
Gewinnen Sie den
Dies gibt einen FehlerWarning: [react-router] You cannot change <Router routes>; it will be ignored
Hareesh
Bitte öffnen Sie eine neue Frage und teilen Sie Ihren Code dort.
Gewinnen Sie am
95

Ich habe dies verwendet, um auf die ID in meiner Komponente zuzugreifen:

<Route path="/details/:id" component={DetailsPage}/>

Und in der Detailkomponente:

export default class DetailsPage extends Component {
  render() {
    return(
      <div>
        <h2>{this.props.match.params.id}</h2>
      </div>
    )
  }
}

Dadurch wird jede ID in einem h2 gerendert, hoffentlich hilft das jemandem.

Alexander Luna
quelle
2
Fantastisch! Mir fehlte der Teil ".params"! Vielen Dank!
Pedro Emilio Borrego Rached
9
Dies sollte die akzeptierte Antwort sein, es ist sauberer und einfacher.
Shukri Adams
27

Verwenden Sie die Rendermethode:

<Route exact path="/details/:id" render={(props)=>{
    <DetailsPage id={props.match.params.id}/>
}} />

Und Sie sollten in der Lage sein, auf die ID zuzugreifen, indem Sie:

this.props.id

Innerhalb der DetailsPage-Komponente

Steven Daniel Anderson
quelle
3
Dies funktioniert übrigens auch mit der Komponentenmethode:<Route path="/..." component={props => <DetailsPage id={props.match.params.id}/>}/>
Mirko Brandt
9

Seit React-Router v5.1 mit Hooks:

import { useParams } from 'react-router';

export default function DetailsPage() {
  const { id } = useParams();
}

Siehe https://reacttraining.com/blog/react-router-v5-1/

user1338062
quelle
1
Dies ist die beste Lösung
Wayneio
7

Zusätzlich zu Alexander Lunas Antwort ... Wenn Sie mehr als ein Argument hinzufügen möchten, verwenden Sie einfach:

<Route path="/details/:id/:title" component={DetailsPage}/>

export default class DetailsPage extends Component {
  render() {
    return(
      <div>
        <h2>{this.props.match.params.id}</h2>
        <h3>{this.props.match.params.title}</h3>
      </div>
    )
  }
}
Manuel
quelle
7

Verwenden Sie die Komponente:

<Route exact path="/details/:id" component={DetailsPage} />

Und Sie sollten in der Lage sein, auf Folgendes zuzugreifen id:

this.props.match.params.id

Innerhalb der DetailsPageKomponente

Dekel
quelle
Interessant funktioniert das. Warum war dies jedoch separat, weil ich eine Variable an die Komponente übergeben wollte. <Route exact path="/details/:id" > <DetailsPage globalStore={globalStore} /> </Route> Das Übergeben des globalStore funktioniert jetzt nicht mehr.
Mudit Tuli
1
@Dekel Ich versuche genau das Gleiche zu tun, aber ich erhalte eine Fehlermeldung. Also habe ich eine neue Frage erstellt. link: stackoverflow.com/questions/52652521/… Ich versuche so einfach auf die ID in der Konsole zuzugreifen.
Arnab
Anstelle von 'Komponente' auf 'Route' wird bei Verwendung von 'Rendern' eine gute Leistung
erzielt
4

Eine andere Lösung besteht darin, einen Status- und Lebenszyklus-Hook in der gerouteten Komponente und eine Suchanweisung in der toEigenschaft der <Link />Komponente zu verwenden. Auf die Suchparameter kann später zugegriffen werden über new URLSearchParams();

<Link 
  key={id} 
  to={{
    pathname: this.props.match.url + '/' + foo,
    search: '?foo=' + foo
  }} />

<Route path="/details/:foo" component={DetailsPage}/>

export default class DetailsPage extends Component {

    state = {
        foo: ''
    }

    componentDidMount () {
        this.parseQueryParams();
    }

    componentDidUpdate() {
        this.parseQueryParams();
    }

    parseQueryParams () {
        const query = new URLSearchParams(this.props.location.search);
        for (let param of query.entries()) {
            if (this.state.foo!== param[1]) {
                this.setState({foo: param[1]});
            }
        }
    }

      render() {
        return(
          <div>
            <h2>{this.state.foo}</h2>
          </div>
        )
      }
    }
Manuel
quelle
3

Hier ist eine Typoskript-Version. arbeitet weiter"react-router-dom": "^4.3.1"

export const AppRouter: React.StatelessComponent = () => {
    return (
        <BrowserRouter>
            <Switch>
                <Route exact path="/problem/:problemId" render={props => <ProblemPage {...props.match.params} />} />
                <Route path="/" exact component={App} />
            </Switch>
        </BrowserRouter>
    );
};

und Komponente

export class ProblemPage extends React.Component<ProblemRouteTokens> {

    public render(): JSX.Element {
        return <div>{this.props.problemId}</div>;
    }
}

wo ProblemRouteTokens

Exportschnittstelle ProblemRouteTokens {problemId: string; }}

GSerjo
quelle
Danke, das ist viel besser und einfacher funktioniert großartig
Ridha Rezzag
1
Ich kann bestätigen, dass es auch in v5.1.2 für Klassenkomponenten funktioniert
Matteus Barbosa
1

Wenn Sie eine Klassenkomponente verwenden, verwenden Sie höchstwahrscheinlich den GSerjo-Vorschlag. Übergeben Sie die Parameter über <Route>Requisiten an Ihre Zielkomponente:

exact path="/problem/:problemId" render={props => <ProblemPage {...props.match.params} />}
Matteus Barbosa
quelle
-1

Versuche dies.

<Route exact path="/details/:id" render={(props)=>{return(
    <DetailsPage id={props.match.params.id}/>)
}} />

Auf der Detailseite versuchen Sie dies ...

this.props.id
Akshaj Nair
quelle