mapStateToProps 反应路由器 dom v6 useParams()

mapStateToProps react router dom v6 useParams()

BlogDetailsPage.js

import { connect } from "react-redux";
import { useParams } from "react-router-dom";

const BlogDetailsPage = (props) => {
  const { id } = useParams();
  return <div>Blog Details: {}</div>;
};

const mapStateToProps = (state, props) => {
  const { id } = useParams();
  return {
    blog: state.blogs.find((blog) => {
      return blog.id === id;
    }),
  };
};

export default connect(mapStateToProps)(BlogDetailsPage);

如何在“useParams()”中使用mapStateToProps react-router-dom ?

并且导航到 /slug 路径的任何链接都在 BlogDetailsPage.js 中结束,因为 BlogDetailsPage.js 被嵌套在其他地方所以我无法获得特定的道具传递但路由参数。从我的角度来看,这是完全错误的,但我想不出更好的方法。

Compiled with problems:X

ERROR


src\components\BlogDetailsPage.js
  Line 11:18:  React Hook "useParams" is called in function "mapStateToProps" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word "use"  react-hooks/rules-of-hooks

Search for the keywords to learn more about each error.```

我认为,react hook函数是允许在react组件内部使用的。 在 React 组件之外,不允许使用 React api 钩子函数。 谢谢,我很想帮你解答。

问题

React hooks 只能从 React 函数组件或自定义 React hooks 调用。在这里,它是在既不是 React 组件也不是自定义挂钩的常规 Javascript 函数中调用的。

解决方案

首选

首选方法是直接在组件中使用 React 挂钩。不要使用 connect 高阶组件,而是使用 useSelector 挂钩 select/access state.blogs 数组。

示例:

import { useSelector } from 'react-redux';
import { useParams } from 'react-router-dom';

const BlogDetailsPage = () => {
  const { id } = useParams();
  const blog = useSelector(state => state.blogs.find(
    blog => String(blog.id) === id
  ));

  return <div>Blog Details: {}</div>;
};

export default BlogDetailsPage;

Alternative/Legacy

如果您需要在任何 mapStateToProps 函数中访问路径参数,例如,如果您使用大量的订单代码,那么您将需要创建另一个 HOC 来访问路径参数和将它们作为 props 注入,以便在 mapStateToProps 函数中可用。

示例:

import { useParams, /* other hooks */ } from "react-router-dom";

const withRouter = Component => props => {
  const params = useParams();
  // other hooks, useLocation, useNavigate, etc..
  return <Component {...props} {...{ params, /* other injected props */ }} />;
};

export default withRouter;

...

import { compose } from 'redux';
import { connect } from 'react-redux';
import withRouter from '../path/to/withRouter';

const BlogDetailsPage = ({ blog }) => {
  return <div>Blog Details: {}</div>;
};

const mapStateToProps = (state, { params }) => {
  const { id } = params || {};
  return {
    blog: state.blogs.find((blog) => {
      return String(blog.id) === id;
    }),
  };
};

export default compose(
  withRouter,              // <-- injects a params prop
  connect(mapStateToProps) // <-- props.params accessible
)(BlogDetailsPage);