react-router-dom useParams () всередині компонента класу


14

Я намагаюся завантажити перегляд деталей на основі маршруту реагування-маршрутизатора, який повинен захопити параметр URL (id) і використовувати його для подальшого заповнення компонента.

Мій маршрут виглядає так, /task/:idі мій компонент добре завантажується, поки я не спробую схопити: id з URL-адреси так:

    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;

Це викликає таку помилку, і я не знаю, де правильно реалізувати useParams ().

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

Документи показують лише приклади на основі функціональних компонентів, а не на основі класу.

Дякую за вашу допомогу, я нова реагую.


6
Гачки не працюють на компонентах на основі класу
Dupocas

@Dupocas нормально, що має сенс. Що б ви запропонували, перепишіть клас до функції або використовуйте клас і спробуйте схопити параметр url іншим способом?
Жорре

Обидві дійсні альтернативи. Чи можете ви опублікувати код для useParams? Може, перетворити його на HOC?
Дупокас

Відповіді:


35

Ви можете використовувати withRouterдля цього. Просто загорніть експортований класифікований компонент всередину withRouterта потім ви можете використовувати this.props.match.params.idпараметри, а не використовувати useParams(). Ви також можете отримати будь-яку location, matchабо historyінформацію за допомогою withRouter. Всі вони передаються підthis.props

Використовуючи ваш приклад, це виглядатиме так:

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

Просто як це!


Будь ласка, позначте цю відповідь правильною.
Самуель Конат

3

Параметри передаються через реквізити на об'єкт відповідності.

props.match.params.yourParams

джерело: https://redux.js.org/advanced/usage-with-react-router

Ось приклад із документів, що знищують реквізит у аргументах.

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

1

Оскільки гачки не працюватимуть із компонентами на основі класу, ви можете зв'язати їх у функції та передавати властивості уздовж:

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

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

Але, як сказав @ michael-mayo, я очікую, що саме withRouterце вже працює.


0

Ви не можете зателефонувати на гачок типу "useParams ()" від React.Component.

Найпростіший спосіб, якщо ви хочете використовувати гачки та вже наявний react.component - це створити функцію, а потім зателефонувати React.Component з цієї функції та передати параметр.

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;

Ваш маршрут перемикання все одно буде щось подібне

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

тоді ви зможете отримати ідентифікатор від реквізиту вашого компонента реакції

this.props.taskId

0

Спробуйте щось подібне

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

За допомогою маршрутизатора react 5.1 ви можете отримати ідентифікатор з наступними:

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

і ваш компонент, ніж може отримати доступ до ідентифікатора:

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

const TaskDetail = () => {
  const {id} = useParams();
    return (
      <div>
        Yo {id}
      </div>
    );
};
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.