如何将 URL 参数传递给选择器

Posted

技术标签:

【中文标题】如何将 URL 参数传递给选择器【英文标题】:How do I pass a URL Param to a selector 【发布时间】:2022-01-18 17:02:32 【问题描述】:

我从useParams 收到一个 url 参数。我想使用mapStateToProps 将它传递给选择器。

collection.component.jsx

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

import  selectShopCollection  from "../../redux/shop/shop.selectors";

import './collection.styles.scss'

const Collection = ( collection ) => 
  const  collectionId  = useParams();
  console.log(collection)
  return (
    <div>
      <h1>collection</h1>
    </div>
  )


const mapStateToProps = (state, ownProps) => (
  collection: selectShopCollection(ownProps.match.params.collectionId)(state)
)

export default connect(mapStateToProps)(Collection);

shop.selectors.js

import  createSelector  from "reselect"

const selectShop = state => state.shop

export const selectShopCollections = createSelector([selectShop], shop =>
  shop.collections
)

export const selectShopCollection = collectionUrlParam =>
  createSelector([selectShopCollections], collections =>
    collections.find(collection => collection.id === collectionUrlParam)
  )

我想问题是,我不能使用 match 传递参数,因为 react-router-dom v6 没有在 props 中传递它。有没有其他方法可以将collectionId 传递给选择器selectShopCollection

【问题讨论】:

【参考方案1】:

由于Collection 是一个函数组件,我建议从react-redux 导入useSelector 钩子,这样您就可以直接传递collectionId 匹配参数。它简化了组件 API。 reselect 选择器可以很好地与 useSelector 挂钩。

import  useParams  from "react-router-dom";
import  useSelector  from "react-redux";

import  selectShopCollection  from "../../redux/shop/shop.selectors";
import './collection.styles.scss'

const Collection = () => 
  const  collectionId  = useParams();
  const collection = useSelector(selectShopCollection(collectionId));

  console.log(collection);

  return (
    <div>
      <h1>collection</h1>
    </div>
  )
;

export default Collection;

【讨论】:

【参考方案2】:

集合组件可以通过withRouter 给予道具。但它已被 react-router v6 弃用。因此,我们需要创建自己的 HOC 来包装我们的组件。 我创建了一个这样的 HOC:

import  useParams  from "react-router-dom"

const withRouter = WrappedComponent => props => 
  const params = useParams()

  return (
    <WrappedComponent ...props params=params />
  )


export default withRouter;

查看How to get parameter value from react-router-dom v6 in class 的答案,了解制作此 HOC 的原因。

而且,我们可以将withRouter 导入到组件中,并在compose 中与connect 一起使用。在compose 上阅读更多信息。它只是返回通过从右到左组合给定函数获得的最终函数。

const mapStateToProps = (state, ownProps) => (
  collection: selectShopCollection(ownProps.params.collectionId)(state)
)

export default compose(withRouter, connect(mapStateToProps))(Collection)

【讨论】:

以上是关于如何将 URL 参数传递给选择器的主要内容,如果未能解决你的问题,请参考以下文章

如何将多个参数传递给“scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:”中的选择器

如何将 url 中的工作簿参数传递给 Azure Monitor 工作簿?

如何将变量作为 cURL 数组中的 url 参数传递给 CURLOPT_URL

如何通过将参数传递给 URL 来使用 jQuery 刷新页面

如何通过 URL 将参数传递给闪亮的应用程序

在页面模型中将参数传递给 TestCafe 选择器