connected-react-router icon indicating copy to clipboard operation
connected-react-router copied to clipboard

Peer dependencies

Open andreizanik opened this issue 2 years ago • 14 comments

Updated peer dependencies Support react 18.2.0 and react-redux 8.0.0 https://github.com/supasate/connected-react-router/issues/585 https://github.com/supasate/connected-react-router/issues/577

andreizanik avatar Aug 25 '22 10:08 andreizanik

Please, check this PR

vlone310 avatar Aug 26 '22 09:08 vlone310

@vlone310 I think this project isn't supported I decided to try the package mentioned in the issue https://github.com/supasate/connected-react-router/issues/579

andreizanik avatar Aug 29 '22 07:08 andreizanik

Closes https://github.com/supasate/connected-react-router/issues/612, please merge it

achepukov avatar Mar 21 '23 13:03 achepukov

Closes https://github.com/supasate/connected-react-router/issues/612, please merge it

Unfortunately, author of the repository has not been active for a long time

andreizanik avatar Mar 21 '23 14:03 andreizanik

maybe there is a fork with react v18 support?

achepukov avatar Mar 22 '23 06:03 achepukov

The premise of this library is wrong/ obsolete. With the latest react router the hooks give you the values you need.

-- Sent from Mobile

avindra avatar Mar 22 '23 17:03 avindra

@avindra I have complex selectors, which filters data based on url params (?a=1&b=2). Moving this logic into the a component is not an option for me. Do you have a solution?

achepukov avatar Apr 10 '23 19:04 achepukov

With useSelector, you can pass params as everything is in the same scope. Say for example you had a query param named userId that you wanted to use in your redux selector:

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

const UserProfile = () => {
  const { userId } = useParams();
  const user = useSelector((state) => state.users[userId]);

  return (
    <div>
      <h1>{user.name}</h1>
      <p>Email: {user.email}</p>
      {/* Render more user details */}
    </div>
  );
};

export default UserProfile;

Keep in mind you can swap useParams with your own implementation or a third-party one like use-query-params.

avindra avatar Apr 13 '23 01:04 avindra

If you still have a lot of class-based components (which BTW you should get rid of to keep on track with latest react)... then you can use withRouter to get what you need. E.g.,:

import React from 'react';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';

const UserProfile = ({ user }) => {
  return (
    <div>
      <h1>{user.name}</h1>
      <p>Email: {user.email}</p>
      {/* Render more user details */}
    </div>
  );
};

const mapStateToProps = (state, ownProps) => {
  const userId = ownProps.match.params.userId;
  return {
    user: state.users[userId],
  };
};

export default withRouter(connect(mapStateToProps)(UserProfile));

avindra avatar Apr 13 '23 01:04 avindra

@avindra yeah, thank, but this looks like workaround rather then good fix.

Moving this logic into the a component is not an option for me.

Cuz fix this way means that I add logic into the component which is needed only in selectors. I do not need those values in component, but in selectors only. That's why it's too early to say that

The premise of this library is wrong/ obsolete.

achepukov avatar Apr 13 '23 05:04 achepukov

this looks like workaround

Happy to disagree. FWIW, I removed a hundred or so of these connected router hacks, dropped connected-react-router and the code became much clearer in a codebase with over 80K SLOC.

Once again, useParams is the best option. If you need a connected like approach, then use withRouter.

avindra avatar Apr 13 '23 18:04 avindra

@avindra

I removed a hundred or so of these connected router hacks

could you please explain in detail what exactly you did? I didn't get it. From the example you provided it looks like you did not remove the logic, but moved it into component instead.

achepukov avatar Apr 14 '23 04:04 achepukov

If you use withRouter, everything is done within the selector (using ownProps to access router data).

As you noted, with the useParams approach, some of the code gets moved to the component.

If you need to abstract the selector to a separate function, I suggest creating a hook. I have provided an example for this case.


file: hook.js

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

export function useUser() {
  const { userId } = useParams();
  const user = useSelector((state) => state.users[userId]);
  return user;
}

file: Component.js

import React from 'react';
import {useUser} from './hook.js'

const UserProfile = () => {
  const user = useUser();

  return (
    <div>
      <h1>{user.name}</h1>
      <p>Email: {user.email}</p>
      {/* Render more user details */}
    </div>
  );
};

export default UserProfile;

avindra avatar Apr 17 '23 19:04 avindra

@avindra thanks lot! This looks much better from what I thought initially. But again, create new hook just to filter the selector data based on query params looks less nice then incapsulate this logic in selectors.

achepukov avatar Apr 18 '23 19:04 achepukov