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.

Jorre
la source
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!

Michael Mayo
la source
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>
  )
}
marque
la source
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à.

SmujMaiku
la source
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
RickWeb
la source
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;
Kesav
la source
-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>
    );
};
t-reksio
la source