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

14

Я пытаюсь загрузить подробное представление на основе маршрутаact-router-dom, который должен получить параметр 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.

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

Спасибо за вашу помощь, я новичок, чтобы реагировать.

Jorre
источник
6
Хуки не работают в компонентах, основанных на
классах
@Dupocas хорошо, это имеет смысл. Что бы вы предложили, переписать класс в функцию или использовать класс и попытаться получить параметр url другим способом?
Джорре
Обе действительные альтернативы. Можете выложить код для useParams? Может превратить это в HOC?
Дупокас

Ответы:

36

Вы можете использовать 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уже работает.

SmujMaiku
источник
0

Вы не можете вызвать ловушку, такую ​​как "useParams ()" из 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
RickWeb
источник
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;
Kesav
источник
-3

С реагировать на маршрутизатор 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>
    );
};
т-reksio
источник