react-router-dom useParams () dans le composant de classe


14

J'essaie de charger une vue de détails basée sur une route react-router-dom qui devrait saisir le paramètre URL (id) et l'utiliser pour remplir davantage le composant.

Mon itinéraire ressemble /task/:idet mon composant se charge correctement, jusqu'à ce que j'essaye de saisir l'identifiant: id de l'URL comme suit:

    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;

Cela déclenche l'erreur suivante et je ne sais pas où implémenter correctement useParams ().

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

Les documents ne montrent que des exemples basés sur des composants fonctionnels, et non sur des classes.

Merci pour votre aide, je suis nouveau pour réagir.


6
Les crochets ne fonctionnent pas dans les composants basés sur la classe
Dupocas

@Dupocas ok, c'est logique. Que suggéreriez-vous, réécrivez la classe dans une fonction ou utilisez une classe et essayez de saisir le paramètre url d'une autre manière?
Jorre

Les deux alternatives valides. Pouvez-vous publier le code pour useParams? Peut-être le transformer en un HOC?
Dupocas

Réponses:


36

Vous pouvez utiliser withRouterpour accomplir cela. Enveloppez simplement votre composant classé exporté à l'intérieur de withRouteret ensuite vous pouvez utiliser this.props.match.params.idpour obtenir les paramètres au lieu d'utiliser useParams(). Vous pouvez également obtenir une location, matchou d' historyinformations à l'aide withRouter. Ils sont tous passés sousthis.props

En utilisant votre exemple, cela ressemblerait à ceci:

    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);

Aussi simple que cela!


Veuillez marquer cette réponse comme correcte.
Samuel Konat

3

Les paramètres sont transmis via les accessoires sur l'objet de correspondance.

props.match.params.yourParams

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

Voici un exemple des documents détruisant les accessoires dans les arguments.

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

1

Étant donné que les hooks ne fonctionnent pas avec les composants basés sur une classe, vous pouvez l'encapsuler dans une fonction et transmettre les propriétés:

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

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

Mais, comme l'a dit @ michael-mayo, je pense que c'est ce withRouterqui fonctionne déjà.


0

Vous ne pouvez pas appeler un hook tel que "useParams ()" à partir d'un React.Component.

Le moyen le plus simple si vous souhaitez utiliser des hooks et avoir un react.component existant est de créer une fonction, puis d'appeler le React.Component à partir de cette fonction et de passer le paramètre.

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;

Votre itinéraire de commutation sera toujours quelque chose comme

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

alors vous pourrez obtenir l'id à partir des accessoires de votre composant React

this.props.taskId

0

Essayez quelque chose comme ça

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;

-3

Avec react router 5.1, vous pouvez obtenir l'identifiant avec les éléments suivants:

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

et votre composant qui peut accéder à id:

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

const TaskDetail = () => {
  const {id} = useParams();
    return (
      <div>
        Yo {id}
      </div>
    );
};
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.