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

2.x: Support react 19 #4542

Merged
merged 1 commit into from
May 21, 2024
Merged

2.x: Support react 19 #4542

merged 1 commit into from
May 21, 2024

Conversation

eps1lon
Copy link
Contributor

@eps1lon eps1lon commented May 17, 2024

Best reviewed without whitespace changes

Description

defaultProps are no longer supported on function components. To simplify migration, the components that do rely on the original defaultProps behavior were migrated to class components.

Libraries also need to manually apply defaultProps if they expect that these are resolved by the JSX runtime. In React 19, defaultProps are only resolved by the time the component instances may access props not when a parent renders or reads from the JSX e.g. via children.props.

Related Issue

Motivation and Context

Adds support for React 19 to recharts@2.x without having to patch published files.

Complete React 19 support would require #4541 but that's a breaking change. Consumers of 2.x will have to use resolutions or overrides with their package managers to ensure the correct react-is version is used

How Has This Been Tested?

We've been using recharts in various (internal) surfaces at Vercel. We've applied this patch to our codebase and charts have been working when they were previously broken.

The following components we use explicitly:

  • ResponsiveContainer
  • LineChart
  • CartesianGrid
  • XAxis
  • Tooltip
  • YAxis
  • Legend
  • Line
  • PieChart
  • Cell
  • Pie
  • Sector

We also use SparkAreaChart from @tremor/react which uses recharts to implement that chart.

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • I have added a storybook story or extended an existing story to show my changes

@ckifer
Copy link
Member

ckifer commented May 17, 2024

We are not planning on allowing 2.x to support react 19 because of the many reasons you document here + many other hidden things that will break because of the hacks recharts currently uses to render children and read props from react elements

@eps1lon
Copy link
Contributor Author

eps1lon commented May 17, 2024

That was not our impression when testing. What else is broken in your opinion?

@ckifer
Copy link
Member

ckifer commented May 18, 2024

Recharts relies on element cloning and reading information props react components before and after they are rendered.

We are removing all of that in 3.x so we can make changes without breaking things accidentally. And follow current react practices so recharts is easier to contribute to.

I guess I'd be fine accepting this PR to "support" react 19, but this branch will no longer get updates once 3.0 is released. Right now just trying to keep it to backwards compatible bug fixes.

Ideally we'd be done with 3.0 before react 19 was released and we would never accept react 19 in 2.x peerDeps. Since we're not done yet I guess this is fine.

Just beware that even though test coverage is high there are still a lot of cases not covered explicitly. The Component.props references are extremely fragile. I don't really want to put out fires if we support react 19 in 2.x and issues start to flood in when things break.

@PavelVanecek
Copy link
Collaborator

PavelVanecek commented May 18, 2024

I mean. If you tested this internally and it works then I suppose it can't be that bad. We could release that as 2.8 2.13.

But otherwise yeah, as @ckifer says, 3.0 is getting closer so I too would prefer if this patch landed in 3.x branch. That branch also has a lot better test coverage.

@ckifer
Copy link
Member

ckifer commented May 18, 2024

Yep, my thoughts exactly

@eps1lon
Copy link
Contributor Author

eps1lon commented May 20, 2024

Libraries should work on compat before a new major is released. Otherwise early adoption by app devs is not possible if they use any library.

@ckifer
Copy link
Member

ckifer commented May 20, 2024

imo this new major is more important due to what the refactoring is accomplishing (removing old react hacks which help compat and maintainability). But either way, this is fine as part of 2.x

Will review and get this merged/released once marked ready/tests are passing

@ckifer ckifer mentioned this pull request May 20, 2024
@staranbeer
Copy link

staranbeer commented May 21, 2024

@ckifer We are testing recharts with react 19 beta in production, everything works fine except for recharts.

Current behavior : (notice that the chart disappears)

image

Expected behavior:

image

We'll be happy to participate in testing this as early adopters and provide feedback on the pr.

@eps1lon
Copy link
Contributor Author

eps1lon commented May 21, 2024

We are testing recharts with react 19 beta in production, everything works fine except for recharts.

Are you using a build from this PR?

@eps1lon eps1lon marked this pull request as ready for review May 21, 2024 12:12
@eps1lon
Copy link
Contributor Author

eps1lon commented May 21, 2024

Will review and get this merged/released once marked ready/tests are passing

@ckifer Ready for review. Will fix tests as CI reveals them but you've configured your repo to block CI from first-time contributors. You can adjust that to only block CI from people new on GitHub which would allow me to iterate.

@eps1lon eps1lon changed the title [WIP] 2.x: Support react 19 2.x: Support react 19 May 21, 2024
@eps1lon eps1lon marked this pull request as draft May 21, 2024 13:31
@eps1lon eps1lon marked this pull request as ready for review May 21, 2024 13:46
@PavelVanecek
Copy link
Collaborator

PavelVanecek commented May 21, 2024

I allowed the CI run but be aware that 2.x branch has very few tests. If you target 3.x there are way more.

Okay correction, 2.x is not as bad as I remember. Still ~2200 tests. 3.x has ~3200 tests. So more but not like game-changing amount more.

@eps1lon
Copy link
Contributor Author

eps1lon commented May 21, 2024

I file a separate PR targetting 3.x. I won't test the 3.x version on React 19 though.

@PavelVanecek
Copy link
Collaborator

Yeah fair enough. 3.x is not ready yet.

@eps1lon
Copy link
Contributor Author

eps1lon commented May 21, 2024

Forward port for 3.x: #4561

@staranbeer
Copy link

We are testing recharts with react 19 beta in production, everything works fine except for recharts.

Are you using a build from this PR?

Not yet. Still waiting for this pr to be merged.

@ckifer
Copy link
Member

ckifer commented May 21, 2024

Pulled down the PR and running chromatic visual different tests https://www.chromatic.com/build?appId=63da8268a0da9970db6992aa&number=972

Storybook from build here https://63da8268a0da9970db6992aa-nwmhgzcfdw.chromatic.com

No visual differences. Feel free to click around to see if anything interactive breaks

This is not on React 19. I will update my local to react 19 and re-run the same test

Comment on lines 52 to 54
offset = 0,
layout = 'horizontal',
width = 5,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Visual regression https://www.chromatic.com/test?appId=63da8268a0da9970db6992aa&id=664cfc9eadd585053f5b885c

This will need to be converted to a class component unfortunately :/

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually... it works in 2.x but not 3.x. Not sure why, we haven't touched error bar much. @PavelVanecek ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll just make it a class component to be safe.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

`defaultProps` are no longer supported on function components.
To simplify migration, the components that do rely on the original defaultProps behavior were migrated to class components.

Libraries also need to manually apply `defaultProps` if they expect that these are resolved by the JSX runtime.
In React 19, defaultProps are only resolved by the time the component instances may access props not when a parent renders or reads from the JSX e.g. via `children.props`.
Copy link
Member

@ckifer ckifer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - I re-ran the visual regression tests on this branch+react 19 and all good.

Imo warrants some more testing though, I might release with an alpha tag

@ckifer ckifer merged commit 28d9ec4 into recharts:master May 21, 2024
5 checks passed
@eps1lon
Copy link
Contributor Author

eps1lon commented May 22, 2024

Imo warrants some more testing though, I might release with an alpha tag

That'd be nice. We'll land the patch in prod start of next week too. Would appreciate an alpha release so that we don't need to retain such a large patch.

@eps1lon eps1lon deleted the support-react-19 branch May 22, 2024 08:58
@ZipBrandon
Copy link

I'm building from this PR and am not seeing my BarCharts nor Donut Charts. Should this PR have addressed all chart types?

@ckifer
Copy link
Member

ckifer commented May 22, 2024

Try installing the beta version of react-is @ZipBrandon

@ZipBrandon
Copy link

@ckifer Thanks for the advisement but unfortunately this still isn't depicting the charts. I made a small project at https://github.com/ZipBrandon/barchart-troubleshooting to get a sanity check on this and the patch.

Here's my npm ls

├── @remix-run/dev@2.9.2
├── @remix-run/node@2.9.2
├── @remix-run/react@2.9.2
├── @remix-run/serve@2.9.2
├── @types/react-dom@18.3.0
├── @types/react@18.3.2
├── @typescript-eslint/eslint-plugin@6.21.0
├── @typescript-eslint/parser@6.21.0
├── autoprefixer@10.4.19
├── eslint-import-resolver-typescript@3.6.1
├── eslint-plugin-import@2.29.1
├── eslint-plugin-jsx-a11y@6.8.0
├── eslint-plugin-react-hooks@4.6.2
├── eslint-plugin-react@7.34.1
├── eslint@8.57.0
├── isbot@4.4.0
├── patch-package@8.0.0
├── react-dom@19.0.0-rc-81c5ff2e04-20240521 overridden
├── react-is@19.0.0-rc-d3ce0d3ea9-20240520 overridden
├── react@19.0.0-rc-81c5ff2e04-20240521 overridden
├── recharts@2.12.7
├── tailwindcss@3.4.3
├── typescript@5.4.5
├── vite-tsconfig-paths@4.3.2
└── vite@5.2.11

@ckifer
Copy link
Member

ckifer commented May 22, 2024

@ZipBrandon here is the storybook of this branch with this PR merged (and upgraded to r19) https://63da8268a0da9970db6992aa-xevoyhcfue.chromatic.com/?path=/story/examples-barchart--stacked

Bars and Pies look fine to me. Don't have time to check your repo yet but i will before I release

@ZipBrandon
Copy link

@ckifer I'm seeing 18.2 on that storybook link
image

@ckifer
Copy link
Member

ckifer commented May 22, 2024

Ok, I'll try to deploy again when I can and double check the version. And also check your repo out

@ckifer
Copy link
Member

ckifer commented May 22, 2024

@ZipBrandon still seems fine to me
https://63da8268a0da9970db6992aa-etgeuylcpn.chromatic.com/?path=/story/api-cartesian-bar--api
I added a react version log on that specific page. It logs 19-beta and charts are rendering without issue

@ZipBrandon
Copy link

@ckifer Thanks for checking that out. Maybe there is something in my build process and patching that is amiss. Can you put out an alpha on npm and I can try that?

@ckifer
Copy link
Member

ckifer commented May 22, 2024

@ZipBrandon It might be remix tbh. I'm starting a new blank vite project (no remix) and making sure that works that for a quick sanity check. Then will go for the alpha release

@ckifer
Copy link
Member

ckifer commented May 23, 2024

@ZipBrandon @eps1lon this is broken. @ZipBrandon if I add xAxisId, yAxisId and minPointSize to your example it works. Otherwise it breaks. These are defaultProp hacks rearing their ugly heads. I can't release this yet

<BarChart
      width={500}
      height={300}
      data={data}
      margin={{
        top: 5,
        right: 30,
        left: 20,
        bottom: 5,
      }}
    >
      <CartesianGrid strokeDasharray="3 3" />
      <XAxis dataKey="name" xAxisId={0}/>
      <YAxis yAxisId={0}/>
      <Tooltip shared={false} trigger="click" />
      <Legend />
      <Bar dataKey="pv" fill="#8884d8"  xAxisId={0} yAxisId={0} minPointSize={10}/>
      <Bar dataKey="uv" fill="#82ca9d"  xAxisId={0}yAxisId={0} minPointSize={10} />
    </BarChart>

@ckifer
Copy link
Member

ckifer commented May 23, 2024

I also don't have the time to fix it so if anyone wants to dive in and make another PR feel free

@ckifer
Copy link
Member

ckifer commented May 23, 2024

80 failed | 2114 passed

Breaks about 80 unit tests when ran with React 19. Good thing is that R18 and below is fine... but we'll need all these to pass to release this

@eps1lon
Copy link
Contributor Author

eps1lon commented May 23, 2024

Breaks about 80 unit tests when ran with React 19. Good thing is that R18 and below is fine... but we'll need all these to pass to release this

Is there a branch I can checkout?

@ckifer
Copy link
Member

ckifer commented May 23, 2024

It's not ideal because you need to upgrade the recharts repo to R19 before things break and you need to upgrade other things (storybook, testing library) before anything works. So it's a bit of a mess. Not sure why storybook doesn't fail but it must be using its own React version or something.

I was using yalc to local publish and test in a fresh repo.

On mobile rn but I'll push the branch up shortly

@ckifer
Copy link
Member

ckifer commented May 23, 2024

@eps1lon https://github.com/recharts/recharts/tree/fix-r19-defaultProps-issues

@ckifer
Copy link
Member

ckifer commented May 24, 2024

Alpha release - https://www.npmjs.com/package/recharts/v/2.13.0-alpha.0
This BREAKS things in R19, shouldn't in R18

use this to determine what is breaking/what isn't. I just don't have bandwidth to fix it myself

@eps1lon
Copy link
Contributor Author

eps1lon commented May 24, 2024

Green test suite: #4573

ckifer pushed a commit that referenced this pull request May 24, 2024
#4542 was incomplete with
regards to `defaultProps`. This PR ensures the test suite is green in
React 19 as well as well as fixing all new warnings introduced in React
19.

---------

Co-authored-by: Coltin Kifer <ckifer@amazon.com>
@bitjoo
Copy link

bitjoo commented May 29, 2024

@eps1lon Thank you for this fix regarding the defaultProps error message from React. I've tested the latest alpha release 2.13.0-alpha.3 and found a type issue with the ReferenceLine. You will quickly see the problem when you check out the test/cartesian/ReferenceLine/ReferenceLine.spec.tsx on line 41.

No overload matches this call.
...
  Property 'x' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<ReferenceLine> & Pick<Readonly<{}>, never> & InexactPartial<...> & InexactPartial<...>'.
...

You can fix it by changing

export class ReferenceLine extends React.Component {

to

export class ReferenceLine extends React.Component<Props> {

in src/cartesian/ReferenceLine.tsx:L196

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

Successfully merging this pull request may close these issues.

None yet

7 participants