sentry-javascript icon indicating copy to clipboard operation
sentry-javascript copied to clipboard

`Sentry.withProfiler` warns `Function components cannot be given refs`

Open marandaneto opened this issue 2 years ago • 2 comments

Is there an existing issue for this?

  • [X] I have checked for existing issues https://github.com/getsentry/sentry-javascript/issues
  • [X] I have reviewed the documentation https://docs.sentry.io/
  • [X] I am using the latest SDK release https://github.com/getsentry/sentry-javascript/releases

How do you use Sentry?

Sentry Saas (sentry.io)

Which package are you using?

@sentry/react

SDK Version

6.19.2

Framework Version

RN SDK 3.4.0

Link to Sentry event

https://sentry.io/organizations/sentry-sdks/performance/sentry-react-native:5a590b7042494447979f144891146342/?project=5428561&query=transaction.duration%3A%3C15m&showTransactions=recent&statsPeriod=1h&transaction=Screen&unselectedSeries=p100%28%29

Steps to Reproduce

Using React Native Navigation from Wix https://docs.sentry.io/platforms/react-native/performance/instrumentation/automatic-instrumentation/#react-native-navigation Using React Profiler https://docs.sentry.io/platforms/javascript/guides/react/components/profiler/

  1. Run sample https://github.com/marandaneto/ReactNativeNavigationInstrumentation/
  2. Look at code https://github.com/marandaneto/ReactNativeNavigationInstrumentation/blob/main/App.js#L47-L50

Expected Result

Warn won't happen and transactions will contain lifecycle spans (from wrapped components).

Actual Result

Console warns Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?.

Spans are created tho.

Screenshot 2022-04-04 at 14 13 28

withProfiler likely has problems using forwarding refs. https://reactjs.org/docs/forwarding-refs.html

marandaneto avatar Apr 04 '22 12:04 marandaneto

We'll need to update the Profiler to work forward the refs. The tricky part is that the React.forwardRef API is only avaliable in React 16.3 and above, and we still support React 15. As such we either need to make this a breaking change to withProfiler, or we create a new HOC withProfilerRef (hopefully with a better name than that lol) to support this.

AbhiPrasad avatar Apr 04 '22 12:04 AbhiPrasad

Links back to Jira: https://getsentry.atlassian.net/jira/software/c/projects/ISSUE/boards/25?modal=detail&selectedIssue=ISSUE-1450

bruno-garcia avatar Jun 20 '22 17:06 bruno-garcia

Why was this issue closed?

While we think it would be helpful to solve this issue, we're busy with a lot of other tasks at the moment. Therefore, this issue is not a priority for us at this time. If you still want to see this resolved, please consider opening a PR for it - we're always happy to review them.

Please feel free to leave a comment if you think this issue should be reopened.

mydea avatar Mar 02 '23 14:03 mydea

Are there any known workaround? useProfiler seems similar, maybe worth pointing to it?

tibotiber avatar Mar 21 '23 04:03 tibotiber

@tibotiber I haven't run this code, but this should do what you need.

import { forwardRef } from 'react';
import hoistNonReactStatics from 'hoist-non-react-statics';
import * as Sentry from '@sentry/react';

function withProfiler(WrappedComponent, options) {
    const componentDisplayName = (options && options.name) || WrappedComponent.displayName || WrappedComponent.name || 'unknown';
    const Wrapped = forwardRef((props, ref) => (
        <Sentry.Profiler {...options} name={componentDisplayName} updateProps={props}>
            <WrappedComponent ref={ref} {...props} />
        </Sentry.Profiler>
    ));

    Wrapped.displayName = `profiler(${componentDisplayName})`;
    hoistNonReactStatics(Wrapped, WrappedComponent);
    return Wrapped;
}

Twipped avatar Apr 06 '23 18:04 Twipped

Thanks @Twipped. I have actually managed to replace withProfiler with useProfiler to get around this issue. Forgot to post here.

tibotiber avatar Apr 10 '23 03:04 tibotiber