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

Viewed 356

In my Application I want to pass the parameter that I'm getting from useParams() to mapStateToProps function which I'm using with reselect Library . I can hardcode the value instead of passing this parameter and everything works as expected. Also, I can pass useParams().routeName directly to mapState function and it's working. But in case of using ownProps it is not working. Here is my code :

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);

With this code the return will be undefined but when I hardcode the value like code below its working :

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

Preferred

The preferred method would be to use the React hooks directly in the component. Instead of using the connect Higher Order Component use the useSelector hook to select/access the collection state. Refactor the selectCollection selector to return the state and do the filtering in the UI.

Example:

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

If you have the need to access path params in any mapStateToProps function, if you are using a lot of oder code for example, then you'll need to create another HOC to access the path params and have them injected as props so they are available in the mapStateToProps function.

Example:

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);
Related