React-Router-Dom UseParams () innerhalb der Klassenkomponente

14

Ich versuche, eine Detailansicht basierend auf einer React-Router-Dom-Route zu laden, die den URL-Parameter (ID) abrufen und damit die Komponente weiter füllen soll.

Meine Route sieht so aus /task/:idund meine Komponente wird einwandfrei geladen, bis ich versuche, die: id von der URL wie folgt abzurufen:

    import React from "react";
    import { useParams } from "react-router-dom";

    class TaskDetail extends React.Component {
        componentDidMount() {
            let { id } = useParams();
            this.fetchData(id);
        }

        fetchData = id => {
            // ...
        };

        render() {
            return <div>Yo</div>;
        }
    }

export default TaskDetail;

Dies löst den folgenden Fehler aus und ich bin mir nicht sicher, wo useParams () korrekt implementiert werden soll.

Error: Invalid hook call. Hooks can only be called inside of the body of a function component.

Die Dokumente zeigen nur Beispiele, die auf Funktionskomponenten basieren, nicht auf Klassen.

Vielen Dank für Ihre Hilfe, ich bin neu zu reagieren.

Jorre
quelle
6
Hooks funktionieren nicht in klassenbasierten Komponenten
Dupocas
@ Dupocas ok das macht Sinn. Was würden Sie vorschlagen, schreiben Sie die Klasse in eine Funktion um oder verwenden Sie eine Klasse und versuchen Sie, den URL-Parameter auf andere Weise abzurufen?
Jorre
Beide gültigen Alternativen. Können Sie den Code für posten useParams? Vielleicht verwandeln Sie es in ein HOC?
Dupocas

Antworten:

35

Sie können dies verwenden withRouter, um dies zu erreichen. Wickeln Sie einfach Ihre exportierte klassifizierte Komponente in ein withRouterund dann können Sie this.props.match.params.iddie Parameter abrufen, anstatt sie zu verwenden useParams(). Sie können erhalten auch alle location, matchoder historyInformationen durch die Verwendung withRouter. Sie sind alle unter übergebenthis.props

Anhand Ihres Beispiels würde es so aussehen:

    import React from "react";
    import { withRouter } from "react-router-dom";

    class TaskDetail extends React.Component {
        componentDidMount() {
            const id = this.props.match.params.id;
            this.fetchData(id);
        }

        fetchData = id => {
            // ...
        };

        render() {
            return <div>Yo</div>;
        }
    }

export default withRouter(TaskDetail);

So einfach ist das!

Michael Mayo
quelle
Bitte markieren Sie diese Antwort richtig.
Samuel Konat
3

Parameter werden durch Requisiten auf dem Match-Objekt weitergegeben.

props.match.params.yourParams

Quelle: https://redux.js.org/advanced/usage-with-react-router

Hier ist ein Beispiel aus den Dokumenten, die die Requisiten in den Argumenten zerstören.

const App = ({ match: { params } }) => {
  return (
    <div>
      <AddTodo />
      <VisibleTodoList filter={params.filter || 'SHOW_ALL'} />
      <Footer />
    </div>
  )
}
Kennzeichen
quelle
1

Da Hooks mit klassenbasierten Komponenten nicht funktionieren, können Sie sie in eine Funktion einschließen und die Eigenschaften weitergeben:

class TaskDetail extends React.Component {
    componentDidMount() {
        const { id } = this.props.params;
        // ...
    }
}

export default (props) => (
    <TaskDetail
        {...props}
        params={useParams()}
    />
);

Aber, wie @ michael-mayo sagte, ich gehe davon aus, dass dies withRouterbereits der Fall ist.

SmujMaiku
quelle
0

Sie können keinen Hook wie "useParams ()" aus einer React.Component aufrufen.

Der einfachste Weg, wenn Sie Hooks verwenden möchten und eine vorhandene react.component haben, besteht darin, eine Funktion zu erstellen. Rufen Sie dann die React.Component von dieser Funktion aus auf und übergeben Sie den Parameter.

import React from 'react';
import useParams from "react-router-dom";

import TaskDetail from './TaskDetail';

function GetId() {

    const { id } = useParams();
    console.log(id);

    return (
        <div>
            <TaskDetail taskId={id} />
        </div>
    );
}

export default GetId;

Ihre Switch-Route wird immer noch so etwas wie sein

<Switch>
  <Route path="/task/:id" component={GetId} />
</Switch>

Dann können Sie die ID von den Requisiten in Ihrer Reaktionskomponente abrufen

this.props.taskId
RickWeb
quelle
0

Versuchen Sie so etwas

import React from "react";
import { useParams } from "react-router-dom";

class TaskDetail extends React.Component {
let { id='' } = useParams();
    componentDidMount() {
        this.fetchData(id);
    }

    fetchData = id => {
        // ...
    };

    render() {
        return <div>Yo</div>;
    }
}

export default TaskDetail;
Kesav
quelle
-3

Mit React Router 5.1 können Sie die ID wie folgt erhalten:

<Switch>
  <Route path="/item/:id" component={Portfolio}>
    <TaskDetail />
  </Route>
</Switch>

und Ihre Komponente als auf ID zugreifen kann:

import React from 'react';
import { useParams} from 'react-router-dom';

const TaskDetail = () => {
  const {id} = useParams();
    return (
      <div>
        Yo {id}
      </div>
    );
};
t-reksio
quelle