Skip to content

Remove unneeded forwardRef and memo#4096

Merged
Ajamuar merged 17 commits intoGeekyAnts:minorfrom
RWOverdijk:patch-1
Sep 27, 2021
Merged

Remove unneeded forwardRef and memo#4096
Ajamuar merged 17 commits intoGeekyAnts:minorfrom
RWOverdijk:patch-1

Conversation

@RWOverdijk
Copy link
Copy Markdown
Contributor

@RWOverdijk RWOverdijk commented Sep 21, 2021

Summary

<Hidden /> was using forwardRef, but not in the right way causing issues: (https://discord.com/channels/785491682719301643/785491683336781846/889862903140847626)

There were two possible fixes I could see. Remove the ref, or implement the ref properly. Since this only performs conditional rendering the ref isn't needed, so I opted to remove it.

Changelog

General Fixed - Remove unused forwardRef in Hidden component
General Fixed - Forward ref in SkeletonCircle

@vercel
Copy link
Copy Markdown

vercel bot commented Sep 21, 2021

@RWOverdijk is attempting to deploy a commit to the Geekyants Team Team on Vercel.

A member of the Team first needs to authorize it.

@daltonconley
Copy link
Copy Markdown

I'm also seeing this issue here:

export default memo(forwardRef(SkeletonCircle));

@exneval
Copy link
Copy Markdown
Contributor

exneval commented Sep 24, 2021

@RWOverdijk just curious, why memo also get removed here?

@RWOverdijk
Copy link
Copy Markdown
Contributor Author

@RWOverdijk just curious, why memo also get removed here?

Nice catch, I removed it because I misunderstood its purpose here. If the props don't change, the component function doesn't have to run again so I put it back.

@RWOverdijk
Copy link
Copy Markdown
Contributor Author

I'm also seeing this issue here:

export default memo(forwardRef(SkeletonCircle));

I've updated SkeletonCircle in this PR, too. In this case it should forward because Skeleton (used in SkeletonCircle) also forwards the ref to Box.

@vidhi499 vidhi499 changed the base branch from master to minor September 27, 2021 07:52
@vercel
Copy link
Copy Markdown

vercel bot commented Sep 27, 2021

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/geekyants-team/native-base/Hb1gTjx4xARcAgoL4GBq1BbBXNFK
✅ Preview: https://native-base-git-fork-rwoverdijk-patch-1-geekyants-team.vercel.app

@Ajamuar Ajamuar merged commit a690b9c into GeekyAnts:minor Sep 27, 2021
import Skeleton from './Skeleton';

const SkeletonCircle = ({ children, ...props }: ISkeletonProps) => {
const SkeletonCircle = ({ children, ...props }: ISkeletonProps, ref: any) => {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This does not appear to be correct, for one, it shouldn't pass the value into the FC like this.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

However, if you follow the other components they appear to have it but it should be ref?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This does not appear to be correct, for one, it shouldn't pass the value into the FC like this.

It should.

However, if you follow the other components they appear to have it but it should be ref?

You mean optional? Because ForwardRefRenderFunction requires a ref, or null, not an optional ref.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

function forwardRef<T, P = {}>(render: ForwardRefRenderFunction<T, P>): ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<T>>;

and

type ForwardedRef<T> = ((instance: T | null) => void) | MutableRefObject<T | null> | null;

    interface ForwardRefRenderFunction<T, P = {}> {
        (props: PropsWithChildren<P>, ref: ForwardedRef<T>): ReactElement | null;
        displayName?: string;
        // explicit rejected with `never` required due to
        // https://github.com/microsoft/TypeScript/issues/36826
        /**
         * defaultProps are not supported on render functions
         */
        defaultProps?: never;
        /**
         * propTypes are not supported on render functions
         */
        propTypes?: never;
    }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

You mean optional? Because ForwardRefRenderFunction requires a ref, or null, not an optional ref.

If we're following consistency with other components they use ref?: any though that to me is incorrect anyway since it bypasses Typescript checking.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sorry I know it was merged, I didn't know I had to press "Submit Review" for it to show.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Some other components also use ref: any. It's not consistent, sure, but it's not wrong. Straightening out this inconsistency could be another PR, but brace yourself because the generics can alternate between mobile and web depending on the components you're talking about.

return resolvedProps.isLoaded ? children : <Skeleton {...resolvedProps} ref={ref} />;
};

export default memo(forwardRef(SkeletonCircle));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

If we follow https://reactjs.org/docs/forwarding-refs.html this is the line that should get the ref as

export default memo(forwardRef((props, ref)=> (<SkeletonCircle ref={ref} {...props} />));

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The fc is the same thing, just assigned elsewhere. It's props and then ref.

In other words the forward ref wants a function that takes props and a ref, which is what SkeletonCircle is. A function that accepts props and a ref.

So I'm not sure what you mean. This seems correct to me.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

forwardRef technically is a typed function. The second type parameter being a props without the Ref. This would've ensured typesafety, but because of how NativeBase used any in the lower level component the typecheck gets confused if you try to do it properly.

For now as long as the warning disappears I guess we should lave it at that.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Forward ref (typescript, for that matter) doesn't care if you inline or pass through a variable.

But I'm not sure what you're suggesting. Do you mean the generics? Because while those are missing (consistently, which is not good), you can still type them in useRef. Not the prettiest, but also not the scope of this PR. It currently resolves (when typing in useRef) using no types at all.

@RWOverdijk RWOverdijk deleted the patch-1 branch September 27, 2021 14:16
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.

6 participants