クラスコンポーネント内のreact-router-dom useParams()


14

URLパラメータ(id)を取得し、それを使用してコンポーネントにさらにデータを入力する、react-router-domルートに基づいて詳細ビューをロードしようとしています。

私のルートは次のように/task/:idなり、次のようにURLから:idを取得しようとするまで、コンポーネントは正常にロードされます。

    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ますか?
Dupocas

回答:


36

withRouterこれを達成するために使用できます。エクスポートしたクラス化されたコンポーネントを内部にラップするだけでwithRouter、を使用this.props.match.params.idする代わりにを使用してパラメーターを取得できますuseParams()。あなたはまた、任意取得することができlocationmatchまたは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);

そのような単純な!


この回答を正解としてマークしてください。
Samuel Konat

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

React.Componentから "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>

その後、あなたはあなたの反応コンポーネントの小道具からIDを取得することができます

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

反応ルータ5.1を使用すると、次のIDを取得できます:

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

そしてあなたのコンポーネントはidにアクセスできます:

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

const TaskDetail = () => {
  const {id} = useParams();
    return (
      <div>
        Yo {id}
      </div>
    );
};
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.