类组件内部的react-router-dom useParams()

时间:2019-10-24 20:31:55

标签: reactjs react-router

我正在尝试基于应获取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 个答案:

答案 0 :(得分:11)

您可以使用withRouter完成此操作。只需将导出的分类组件包装在withRouter内,然后可以使用this.props.match.params.id来获取参数,而不必使用useParams()。您还可以使用location获取任何matchhistorywithRouter信息。它们都在this.props

下传递

以您的示例为例:

    import React from "react";
    import { withRouter } from "react-router";

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

就这么简单!

答案 1 :(得分:2)

Params通过匹配对象上的道具传下来。

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

答案 2 :(得分:2)

由于钩子不能与基于类的组件一起使用,因此您可以将其包装在函数中并传递属性:

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

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

但是,就像@ michael-mayo所说的那样,我希望withRouter已经在执行此操作。

答案 3 :(得分:1)

反应路线v5

查询参数可以使用withRouterqueryString如下读取和处理为JSON:

import React from "react";
import { withRouter } from "react-router";
import queryString from 'query-string';
    
class MyComponent extends React.Component {
    componentDidMount() {
        const params = queryString.parse(this.props.location.search);
        console.log('Do something with it', params);
    }

    render() {
        return <div>Hi!</div>;
    }
}

export default withRouter(MyComponent);

答案 4 :(得分: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>

然后您将可以从react组件中的道具中获取ID

this.props.taskId

答案 5 :(得分:-5)

使用React Router 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>
    );
};