Last active
June 10, 2024 09:20
Revisions
-
gitname revised this gist
Feb 10, 2023 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,8 +1,8 @@ # Using `@react-pdf/renderer` v3.0.1 with React 18 ## Introduction When I tried to use the `@react-pdf/renderer` package (version `3.0.1`) with a React 18 app, two problems arose. In this article, I'll describe those problems and tell you how I solved them. **Update**: Here's a video demonstration of the problems and solution described in this article: https://youtu.be/YZP5r7Uy_bU -
gitname revised this gist
Dec 16, 2022 . 1 changed file with 2 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -4,6 +4,8 @@ When I tried to use the `@react-pdf/renderer` package with a React 18 app, two problems arose. In this article, I'll describe those problems and tell you how I solved them. **Update**: Here's a video demonstration of the problems and solution described in this article: https://youtu.be/YZP5r7Uy_bU ## Problem 1: Dependency Conflict According to its [`package.json`](https://github.com/diegomura/react-pdf/blob/b385dcbc9cf90254bbdafec161e51087249b20fa/packages/renderer/package.json#L40) file, the `@react-pdf/renderer` package (as of version `3.0.1`—the latest version) is only compatible with React versions 16 and 17. Meanwhile, React apps created using `create-react-app` (as of version `5.0.1`—the latest version) run React version 18. -
gitname revised this gist
Dec 16, 2022 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -73,11 +73,11 @@ TS2769: No overload matches this call. Property 'children' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<Svg> & Readonly<SVGProps>' ``` ### Solution: Use custom components To work around that, I define and use custom variants of the affected components. These custom variants _do_ accept a `children` prop. To define the custom variants, I copy/paste the following code into any `.tsx` file in my app's `src/` folder (personally, I put it in a new file at `src/patches/@react-pdf/renderer/index.tsx`): ```tsx import ReactPDF from '@react-pdf/renderer'; -
gitname revised this gist
Dec 16, 2022 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -49,7 +49,7 @@ $ npm install @react-pdf/renderer **Note:** If you are not using TypeScript, you can ignore this problem. The [type definitions of some components](https://github.com/diegomura/react-pdf/blob/b385dcbc9cf90254bbdafec161e51087249b20fa/packages/renderer/index.d.ts#L247) in the `@react-pdf/renderer` package were written under the assumption that any component whose type was `React.Component` would implictly accept a `children` prop. Some people refer to that implict acceptance of a `children` prop as "implicit children." The "implicit children" behavior was [removed from React](https://solverfox.dev/writing/no-implicit-children/) in React 18. However, the type definitions in the `@react-pdf/renderer` package have not been updated accordingly. -
gitname created this gist
Dec 16, 2022 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,121 @@ # Using `@react-pdf/renderer` with React 18 ## Introduction When I tried to use the `@react-pdf/renderer` package with a React 18 app, two problems arose. In this article, I'll describe those problems and tell you how I solved them. ## Problem 1: Dependency Conflict According to its [`package.json`](https://github.com/diegomura/react-pdf/blob/b385dcbc9cf90254bbdafec161e51087249b20fa/packages/renderer/package.json#L40) file, the `@react-pdf/renderer` package (as of version `3.0.1`—the latest version) is only compatible with React versions 16 and 17. Meanwhile, React apps created using `create-react-app` (as of version `5.0.1`—the latest version) run React version 18. Trying to install the `@react-pdf/renderer` package into such an app results in a **dependency conflict**: ```shell $ npm install @react-pdf/renderer ... npm ERR! Could not resolve dependency: npm ERR! peer react@"^16.8.6 || ^17.0.0" from @react-pdf/[email protected] npm ERR! node_modules/@react-pdf/renderer npm ERR! @react-pdf/renderer@"*" from the root project ``` ### Solution A: Use `--legacy-peer-deps` option **Note**: I recommend Solution B. I am only documenting Solution A for reference, since I have seen several people propose it. One workaround people have proposed is that developers use the `--legacy-peer-deps` option when installing the `@react-pdf/renderer` package. I don't like this approach because (a) it requires me to include that command-line option every time I install _any_ package after that; and (b) it skips peer dependency checks for _all_ packages, not just for `@react-pdf/renderer`. ```shell $ npm install @react-pdf/renderer --legacy-peer-deps ``` ### Solution B: Use `overrides` property A different workaround—and the one I prefer—is to use the [`overrides`](https://docs.npmjs.com/cli/v8/configuring-npm/package-json#overrides) property in my app's `package.json` file. This tells NPM that `@react-pdf/renderer` _really_ depends upon React 18. Unlike with the other workaround; here, (a) the "override" remains documented in `package.json` and (b) only the `@react-pdf/renderer` package and its descendants are affected. ```json "overrides": { "@react-pdf/renderer": { "react": "^18.0.0" } }, ``` ```shell $ npm install @react-pdf/renderer ``` ## Problem 2: Inaccurate TypeScript types **Note:** If you are not using TypeScript, you can ignore this problem. The [type definitions of some components](https://github.com/diegomura/react-pdf/blob/master/packages/renderer/index.d.ts#L247) in the `@react-pdf/renderer` package were written under the assumption that any component whose type was `React.Component` would implictly accept a `children` prop. Some people refer to that implict acceptance of a `children` prop as "implicit children." The "implicit children" behavior was [removed from React](https://solverfox.dev/writing/no-implicit-children/) in React 18. However, the type definitions in the `@react-pdf/renderer` package have not been updated accordingly. As a result, trying to render any of the affected components with child elements, like this... ```tsx import { Svg } from "@react-pdf/renderer"; const MyComponent = () => ( <Svg> {/* child elements go here */} </Svg> ); ``` ...results in a **compiler error**: ```shell TS2769: No overload matches this call. ... Property 'children' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<Svg> & Readonly<SVGProps>' ``` ### Solution: Restore `children` prop To work around that, I define and use custom variants of the affected components. These custom variants _do_ accept a `children` prop. To define the custom variants, I copy/paste the following code into any `.tsx` file in my app's `src/` folder (I, personally, put it in a new file at `src/patches/@react-pdf/renderer/index.tsx`): ```tsx import ReactPDF from '@react-pdf/renderer'; import { FC, PropsWithChildren } from 'react'; // Custom variants of `@react-pdf/renderer` components, which accept a `children` prop. // // Credits: Special thanks to GitHub user @antoineharel for sharing this solution at: // https://github.com/diegomura/react-pdf/pull/1798#issuecomment-1259552615 export const Svg: FC<PropsWithChildren<ReactPDF.SVGProps>> = ({ ...props }) => ( <ReactPDF.Svg {...props} /> ); export const G: FC<PropsWithChildren<ReactPDF.GProps>> = ({ ...props }) => ( <ReactPDF.G {...props} /> ); export const ClipPath: FC<PropsWithChildren<ReactPDF.ClipPathProps>> = ({ ...props }) => ( <ReactPDF.ClipPath {...props} /> ); ``` Now, whenever I would normally import any of the affected components, I import the _custom variant_ instead of the original `@react-pdf/renderer` variant: ```diff import { Svg - } from "@react-pdf/renderer"; + } from "../patches/@react-pdf/renderer"; const MyComponent = () => ( <Svg> {/* child elements go here */} </Svg> ); ``` ## Conclusion With the above solutions in place, I use `@react-pdf/renderer` with React 18.