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

Resolve defaultProps Deprecation- in #677

Open
AlaeddineJendoubi opened this issue Jan 29, 2025 · 3 comments
Open

Resolve defaultProps Deprecation- in #677

AlaeddineJendoubi opened this issue Jan 29, 2025 · 3 comments

Comments

@AlaeddineJendoubi
Copy link

Hi! 👋

Firstly, thanks for your work on this project! 🙂

Today I used patch-package to patch react-native-render-html@6.3.4 for the project I'm working on.

Issue is due to the fact defaultProps will be depricated and kept on throwing errors in TChildrenRenderer / TNodeChildrenRenderer / TNodeRenderer

Here is the diff that solved my problem:

diff --git a/node_modules/react-native-render-html/src/TChildrenRenderer.tsx b/node_modules/react-native-render-html/src/TChildrenRenderer.tsx
index 618a592..013cc0d 100644
--- a/node_modules/react-native-render-html/src/TChildrenRenderer.tsx
+++ b/node_modules/react-native-render-html/src/TChildrenRenderer.tsx
@@ -6,8 +6,10 @@ import renderChildren from './renderChildren';
  * A component to render collections of tnodes.
  * Especially useful when used with {@link useTNodeChildrenProps}.
  */
-const TChildrenRenderer: FunctionComponent<TChildrenRendererProps> =
-  renderChildren.bind(null);
+const TChildrenRenderer: FunctionComponent<TChildrenRendererProps> = (props) => {
+  const mergedProps = { ...tchildrenRendererDefaultProps, ...props };
+  return renderChildren(mergedProps);
+};
 
 export const tchildrenRendererDefaultProps: Pick<
   TChildrenRendererProps,
@@ -16,9 +18,6 @@ export const tchildrenRendererDefaultProps: Pick<
   propsForChildren: {}
 };
 
-/**
- * @ignore
- */
-TChildrenRenderer.defaultProps = tchildrenRendererDefaultProps;
+
 
 export default TChildrenRenderer;
diff --git a/node_modules/react-native-render-html/src/TNodeChildrenRenderer.tsx b/node_modules/react-native-render-html/src/TNodeChildrenRenderer.tsx
index bf5aef6..201320f 100644
--- a/node_modules/react-native-render-html/src/TNodeChildrenRenderer.tsx
+++ b/node_modules/react-native-render-html/src/TNodeChildrenRenderer.tsx
@@ -57,25 +57,17 @@ export function useTNodeChildrenProps({
   };
 }
 
-/**
- * A component to render all children of a {@link TNode}.
- */
-function TNodeChildrenRenderer(
-  props: TNodeChildrenRendererProps
-): ReactElement {
-  if (props.tnode.type === 'text') {
-    // see https://github.com/DefinitelyTyped/DefinitelyTyped/issues/20544
-    return props.tnode.data as unknown as ReactElement;
+function TNodeChildrenRenderer(props: TNodeChildrenRendererProps): ReactElement {
+  const { tnode, ...restProps } = {
+    ...tchildrenRendererDefaultProps,
+    ...props, 
+  };
+
+  if (tnode.type === 'text') {
+    return tnode.data as unknown as ReactElement;
   }
-  // A tnode type will never change. We can safely
-  // ignore the non-conditional rule of hooks.
-  // eslint-disable-next-line react-hooks/rules-of-hooks
-  return renderChildren(useTNodeChildrenProps(props));
-}
 
-/**
- * @ignore
- */
-TNodeChildrenRenderer.defaultProps = tchildrenRendererDefaultProps;
+  return renderChildren(useTNodeChildrenProps({ tnode, ...restProps }));
+}
 
 export default TNodeChildrenRenderer;
diff --git a/node_modules/react-native-render-html/src/TNodeRenderer.tsx b/node_modules/react-native-render-html/src/TNodeRenderer.tsx
index d32140f..c277c80 100644
--- a/node_modules/react-native-render-html/src/TNodeRenderer.tsx
+++ b/node_modules/react-native-render-html/src/TNodeRenderer.tsx
@@ -38,13 +38,21 @@ function isGhostTNode(tnode: TNode) {
   );
 }
 
+const defaultProps: Required<Pick<TNodeRendererProps<any>, 'propsFromParent'>> =
+  {
+    propsFromParent: {
+      collapsedMarginTop: null
+    }
+  };
+
+
 /**
  * A component to render any {@link TNode}.
  */
 const TNodeRenderer = memo(function MemoizedTNodeRenderer(
   props: TNodeRendererProps<any>
 ): ReactElement | null {
-  const { tnode } = props;
+  const { tnode } = {...props, ...defaultProps};
   const sharedProps = useSharedProps();
   const renderRegistry = useRendererRegistry();
   const TNodeChildrenRenderer = useTNodeChildrenRenderer();
@@ -120,15 +128,7 @@ const TNodeRenderer = memo(function MemoizedTNodeRenderer(
     : React.createElement(Renderer as any, assembledProps);
 });
 
-const defaultProps: Required<Pick<TNodeRendererProps<any>, 'propsFromParent'>> =
-  {
-    propsFromParent: {
-      collapsedMarginTop: null
-    }
-  };
 
-// @ts-expect-error default props must be defined
-TNodeRenderer.defaultProps = defaultProps;
 
 export {
   TDefaultBlockRenderer,
diff --git a/node_modules/react-native-render-html/src/TRenderEngineProvider.tsx b/node_modules/react-native-render-html/src/TRenderEngineProvider.tsx
index 95b60df..1e6277a 100644
--- a/node_modules/react-native-render-html/src/TRenderEngineProvider.tsx
+++ b/node_modules/react-native-render-html/src/TRenderEngineProvider.tsx
@@ -98,7 +98,7 @@ export function useAmbientTRenderEngine() {
 export default function TRenderEngineProvider({
   children,
   ...config
-}: PropsWithChildren<TRenderEngineConfig>): ReactElement {
+}: PropsWithChildren<TRenderEngineConfig> = defaultTRenderEngineProviderProps): ReactElement {
   const engine = useTRenderEngine(config);
   return (
     <TRenderEngineContext.Provider value={engine}>
@@ -106,13 +106,3 @@ export default function TRenderEngineProvider({
     </TRenderEngineContext.Provider>
   );
 }
\ No newline at end of file
-
-/**
- * @ignore
- */
-TRenderEngineProvider.defaultProps = defaultTRenderEngineProviderProps;
-
-/**
- * @ignore
- */
-TRenderEngineProvider.propTypes = tRenderEngineProviderPropTypes;

This issue body was partially generated by patch-package.

@simoneldevig
Copy link

Thanks for the fix @AlaeddineJendoubi

I found out the useTRenderEngine to needs to consist of both defaultTRenderEngineProviderProps and config

Doing it like this fixes it: const engine = useTRenderEngine({ ...defaultTRenderEngineProviderProps, ...config });

@tasugi
Copy link

tasugi commented Apr 1, 2025

Thanks all!

I also found that IMGElement should be fixed too.

diff --git a/src/elements/IMGElement.tsx b/src/elements/IMGElement.tsx
index 573e7c15b63d7ab0294a8a96ba06cbbf0fbd139a..71b90d6a62b0aa137c5c1bc422bb5b1f0a7a8594 100644
--- a/src/elements/IMGElement.tsx
+++ b/src/elements/IMGElement.tsx
@@ -14,6 +14,13 @@ function identity(arg: any) {
   return arg;
 }
 
+const defaultProps = {
+  enableExperimentalPercentWidth: false,
+  computeMaxWidth: identity,
+  imagesInitialDimensions: defaultImageInitialDimensions,
+  style: {}
+};
+
 /**
  * A component to render images based on an internal loading state.
  *
@@ -24,7 +31,11 @@ function identity(arg: any) {
  * and {@link IMGElementContentError} for customization.
  */
 function IMGElement(props: IMGElementProps): ReactElement {
-  const state = useIMGElementState(props);
+  const mergedProps = {
+    ...defaultProps,
+    ...props
+  };
+  const state = useIMGElementState(mergedProps);
   let content: ReactNode;
   if (state.type === 'success') {
     content = React.createElement(IMGElementContentSuccess, state);
@@ -35,51 +46,13 @@ function IMGElement(props: IMGElementProps): ReactElement {
   }
   return (
     <IMGElementContainer
-      testID={props.testID}
-      {...props.containerProps}
-      onPress={props.onPress}
+      testID={mergedProps.testID}
+      {...mergedProps.containerProps}
+      onPress={mergedProps.onPress}
       style={state.containerStyle}>
       {content}
     </IMGElementContainer>
   );
 }
 
-const imgDimensionsType = PropTypes.shape({
-  width: PropTypes.number,
-  height: PropTypes.number
-});
-
-const propTypes: Record<keyof IMGElementProps, any> = {
-  source: PropTypes.object.isRequired,
-  alt: PropTypes.string,
-  altColor: PropTypes.string,
-  height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
-  width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
-  style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
-  computeMaxWidth: PropTypes.func.isRequired,
-  contentWidth: PropTypes.number,
-  enableExperimentalPercentWidth: PropTypes.bool,
-  initialDimensions: imgDimensionsType,
-  onPress: PropTypes.func,
-  testID: PropTypes.string,
-  objectFit: PropTypes.string,
-  cachedNaturalDimensions: imgDimensionsType,
-  containerProps: PropTypes.object
-};
-
-/**
- * @ignore
- */
-IMGElement.propTypes = propTypes;
-
-/**
- * @ignore
- */
-IMGElement.defaultProps = {
-  enableExperimentalPercentWidth: false,
-  computeMaxWidth: identity,
-  imagesInitialDimensions: defaultImageInitialDimensions,
-  style: {}
-};
-
 export default IMGElement;

I use pnpm patch.

@Thenlie
Copy link

Thenlie commented Apr 1, 2025

I noticed this fix seems to have already been done in f0c7e34 but not yet released. Any timeline on when this might be released? The patches do work (thanks everyone for the suggestions) but I would like to avoid maintaining another patch file if possible.

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

No branches or pull requests

4 participants