【问题标题】:How do I pass a URL Param to a selector如何将 URL 参数传递给选择器
【发布时间】: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

【问题讨论】:

    标签: reactjs react-hooks react-router-dom reselect mapstatetoprops


    【解决方案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)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-31
        • 2011-04-22
        • 1970-01-01
        • 1970-01-01
        • 2018-11-06
        • 1970-01-01
        相关资源
        最近更新 更多