如何将 URL 参数传递给选择器
How do I pass a URL Param to a selector
我从 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
?
Collection组件可以由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 上阅读更多内容。它只是returns通过从右到左组合给定函数获得的最终函数。
const mapStateToProps = (state, ownProps) => ({
collection: selectShopCollection(ownProps.params.collectionId)(state)
})
export default compose(withRouter, connect(mapStateToProps))(Collection)
因为 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;
我从 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
?
Collection组件可以由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 上阅读更多内容。它只是returns通过从右到左组合给定函数获得的最终函数。
const mapStateToProps = (state, ownProps) => ({
collection: selectShopCollection(ownProps.params.collectionId)(state)
})
export default compose(withRouter, connect(mapStateToProps))(Collection)
因为 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;