我如何使用 React router v6 将 useParams 传递给 React 中的 mapStateToProps?

How can i pass useParams to mapStateToProps in React with react router v6?

在我的应用程序中,我想将从 useParams() 获得的参数传递给 mapStateToProps 函数,该函数与 reselect Library 一起使用。 我可以对值进行硬编码而不是传递此参数,一切都会按预期进行。此外,我可以将 useParams().routeName 直接传递给 mapState 函数并且它正在运行。但在使用 ownProps 的情况下,它不起作用。这是我的代码:

const CollectionPage = ({collection}) => {
  let params = useParams();
  let collectionPath = params.routeName;

  return (
    <div className='collection-page'>
    </div>
  )
}



const mapStateToProps = (state, ownProps) => ({
  collection: selectCollection(ownProps.collectionPath)(state)
});

export default connect(mapStateToProps)(CollectionPage);

使用此代码,return 将是未定义的,但是当我对值进行硬编码时,就像下面的代码一样:

const mapStateToProps = (state) => ({
  collection: selectCollection(''Some Hard Coded Value'')(state)
});

首选

首选方法是直接在组件中使用 React 挂钩。不要使用 connect 高阶组件,而是使用 useSelector 挂钩到 select/access collection 状态。将 selectCollection 选择器重构为 return 状态并在 UI.

中进行过滤

示例:

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

const CollectionPage = () => {
  const { routeName } = useParams();
  const collection = useSelector(state => {
    const collection = selectCollection(state);
    // logic to return collection filtered by routeName, etc...
    return <UI value here>
  });

  return (
    <div className='collection-page'>
      ...
    </div>
  );
};

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 CollectionPage = ({ collection }) => {
  return (
    <div className='collection-page'>
      ...
    </div>
  );
};

const mapStateToProps = (state, { params: { routeName } = {} }) => ({
  collection: selectCollection(routeName)(state),
});

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