Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request for Downgrading react-redux Dependency in react-querybuilder 7.x to Support React 16.x Compatibility #676

Open
andyforever opened this issue Mar 20, 2024 · 4 comments

Comments

@andyforever
Copy link

React Query Builder version

7.x

Platform

No response

Description

The react-querybuilder 7.x version depends on react-redux ^9.1.0, which in turn requires React version 18.0 or higher. I am not certain if react-redux 8.x would be compatible with react-querybuilder 7.x, so I'm wondering if it's possible to downgrade react-redux to the 8.x version.

Reproduction

react-redux package.json

{
    // ...
     "peerDependencies": {
       // ...
        "react": "^18.0"
  },
}

Expected behavior

No response

Additional information

No response

@andyforever andyforever changed the title react-querybuilder 7.x does not support react 16.x,can you guys downgrade the react-redux version to 8.x? Request for Downgrading react-redux Dependency in react-querybuilder 7.x to Support React 16.x Compatibility Mar 20, 2024
@jakeboone02
Copy link
Member

I'm not inclined to downgrade that dependency in RQB for a couple of reasons, one being selfish: the TypeScript types in v7 were really hard to get right and I don't want to revisit them.

The react-redux team's reasoning for bumping the minimum React version to 18 with v9 was (besides reducing their testing requirements) that React 18 had been out for over 1.5 years. We're now 9 days away from the two year anniversary, so it doesn't feel unreasonable to me--that's my second reason.

Can I ask why you're still using React 16? Usually it's organizational bureaucracy and not a technical limitation, but since RQB is generally used for enterprise applications I like to know what sort of friction you're dealing with.

If I was to attempt downgrading the dependency, it would mean moving react-redux (and probably @reduxjs/toolkit) to devDependencies with their current versions and peerDependencies with the absolute minimum versions. Two problems I can think of with that: 1) Users would have to install those packages explicitly, which I'd like to avoid, and 2) the RQB v7 type definitions include some types from react-redux and @reduxjs/toolkit that I'm pretty sure are different from their respective "latest major minus one" versions, which could cause unnecessary pain.

If I'm wrong about any of those assumptions, I'm happy to reevaluate. I'm by no means an expert at this stuff (despite having maintained an open source package for several years!).

@andyforever
Copy link
Author

andyforever commented Mar 21, 2024

Thanks for your reply.

Indeed, as you mentioned, the reason I am still using React 16 is that I am maintaining an enterprise-level application developed using some low-code platforms (you can think of it as similar to Salesforce's development platform), which currently only supports React 16.

When I used the latest version of RQB, it strongly depended on the React.useSyncExternalStore API because of react-redux v9, and this API is only available from React 18. Although there is a shim version for compatibility, v9 does not use it. Also I spent over half of the day to resolve the ESM building problems of RTK v2 before I found the react-redux v9 issue.😂

I can guess that RQB v7 might use react-redux for unified data state management, but I believe that React's own Context API or hooks could also solve this problem without the need to introduce react-redux, which seems a bit too heavy compared to React's own APIs.

I fully understand your reasons for not wanting to downgrade, and indeed React 16 is somewhat outdated at this point. Currently, I can choose RQB v6 as an alternative, which works well with React 16.

By the way, as a reminder, the peerDependencies of RQB v7 might need to be modified since it can no longer support React 16. 🙂

@jakeboone02
Copy link
Member

Indeed, as you mentioned, the reason I am still using React 16 is that I am maintaining an enterprise-level application developed using some low-code platforms (you can think of it as similar to Salesforce's development platform), which currently only supports React 16.

Yeah, I figured as much.

Also I spent over half of the day to resolve the ESM building problems of RTK v2 before I found the react-redux v9 issue.😂

So sorry about that!

By the way, as a reminder, the peerDependencies of RQB v7 might need to be modified since it can no longer support React 16. 🙂

That's a good point. Thanks for the reminder! I need to update the changelog and v7 migration guide as well.

I can guess that RQB v7 might use react-redux for unified data state management, but I believe that React's own Context API or hooks could also solve this problem without the need to introduce react-redux, which seems a bit too heavy compared to React's own APIs.

I did go through some iterations of v7 pre-release that used React's context API and even useState/useReducer, but I couldn't get them to meet my requirements without rolling a bunch of my own stuff on top, at which point I figured I might as well use Redux. (I also tried Zustand, Jotai, MobX, and some others.) The issue wasn't even really about state management per se. I wanted two things: 1) to avoid unnecessary updates to rules and groups that weren't affected by changes to other parts of the query, and 2) to provide access to the full query plus an update method without passing a query prop down to every component in the tree. A prop like that would force a re-render of the entire component tree on every change to the query, defeating memoization 100% of the time and violating my first requirement. A useSelector hook from react-redux, however, can provide a deep subcomponent access to the full root query without requiring the component's ancestors (and therefore all of their descendants) to re-render.

For my money, React context and useState don't solve the same problems as Redux. The lead maintainer of Redux agrees, unsurprisingly.

All that said, if it wasn't for the TypeScript issues I might actually consider downgrading the dependency. Do you think there may be a way to force react-redux v9 to use the shim like v8? If that's the only real holdup to using React 16 it's probably worth investigating.

@andyforever
Copy link
Author

andyforever commented Mar 21, 2024

One reason for performance and another for convenience. Sounds pretty reasonable.

Do you think there may be a way to force react-redux v9 to use the shim like v8? If that's the only real holdup to using React 16 it's probably worth investigating.

Forcing react-redux v9 to use the shim is challenging without modifying the source code, and such modifications are not in line with the intentions of the react-redux team. As they mentioned:

React-Redux 7.x and 8.x worked with all versions of React that had hooks (16.8+, 17.x, 18.x). However, React-Redux v8 used React 18's new useSyncExternalStore hook. In order to maintain backwards compatibility with older React versions, we used the use-sync-external-store "shim" package that provided an official userland implementation of the useSyncExternalStore hook when used with React 16 or 17. This meant that if you were using React 18, there were a few hundred extra bytes of shim code being imported even though it wasn't needed.

Maybe we can add some code at the entry file of RQB like this:

import React from 'react';
import shime from 'use-sync-external-store/shim';

React.useSyncExternalStore = React.useSyncExternalStore || shim.useSyncExternalStore;

Do not forget npm install use-sync-external-store -S before use.

I wonder if you would have a try. Appreciate for that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants