Expected behavior
When providing a reference to a class component totooltipComponent(for asteps props, it will render without error.
Actual behavior
When providing a class component (rather than an element), it errors out withcannot call class as a function.
Steps to reproduce the problem
Create a class component a laclass CustomTooltip extends React.Component {...}. Pass a reference the class you just created to thetooltipComponentprop of the step.
React version
16.2.0
React-Joyride version
^2.0.0-13
Browser name and version
Chrome 67.0
Error stack (if available)
Tooltip.jsx?2cfc:5 Uncaught TypeError: Cannot call a class as a function
at _classCallCheck (Tooltip.jsx?2cfc:5)
at Tooltip (Tooltip.jsx?2cfc:23)
at JoyrideTooltip.render (index.js?3c59:1721)
at finishClassComponent (react-dom.development.js?f8c1:7873)
at updateClassComponent (react-dom.development.js?f8c1:7850)
at beginWork (react-dom.development.js?f8c1:8225)
at performUnitOfWork (react-dom.development.js?f8c1:10224)
at workLoop (react-dom.development.js?f8c1:10288)
at HTMLUnknownElement.callCallback (react-dom.development.js?f8c1:542)
at Object.invokeGuardedCallbackDev (react-dom.development.js?f8c1:581)
_classCallCheck @ Tooltip.jsx?2cfc:5
Tooltip @ Tooltip.jsx?2cfc:23
render @ index.js?3c59:1721
finishClassComponent @ react-dom.development.js?f8c1:7873
updateClassComponent @ react-dom.development.js?f8c1:7850
beginWork @ react-dom.development.js?f8c1:8225
performUnitOfWork @ react-dom.development.js?f8c1:10224
workLoop @ react-dom.development.js?f8c1:10288
callCallback @ react-dom.development.js?f8c1:542
invokeGuardedCallbackDev @ react-dom.development.js?f8c1:581
invokeGuardedCallback @ react-dom.development.js?f8c1:438
renderRoot @ react-dom.development.js?f8c1:10366
performWorkOnRoot @ react-dom.development.js?f8c1:11014
performWork @ react-dom.development.js?f8c1:10967
requestWork @ react-dom.development.js?f8c1:10878
scheduleWorkImpl @ react-dom.development.js?f8c1:10732
scheduleWork @ react-dom.development.js?f8c1:10689
scheduleTopLevelUpdate @ react-dom.development.js?f8c1:11193
updateContainer @ react-dom.development.js?f8c1:11231
(anonymous) @ react-dom.development.js?f8c1:15226
unbatchedUpdates @ react-dom.development.js?f8c1:11102
renderSubtreeIntoContainer @ react-dom.development.js?f8c1:15225
render @ react-dom.development.js?f8c1:15290
(anonymous) @ index.jsx?0ed3:470
setTimeout (async)
(anonymous) @ index.jsx?0ed3:409
If you want to get this issue fixed quickly, make sure to send a public URL or codesandbox example.
No codesandbox since repro steps should cover it conceptually.
*bonus round -- some digging
Pretty sure that the block in question (in react-joyride source) is
if (tooltipComponent) {
var renderProps = _extends({}, buttonProps, {
content: content,
continuous: continuous,
index: index,
isLastStep: isLastStep,
locale: locale,
setTooltipRef: setTooltipRef,
size: size,
title: title
});
if (React.isValidElement(tooltipComponent)) {
component = React.cloneElement(tooltipComponent, renderProps);
} else {
component = tooltipComponent(renderProps);
}
}
specifically, the component = tooltipComponent(renderProps); line. It seems like as a workaround you can provide an element like component = <TooltipComponent ...props />. If there's a specific reason why not to do that, I'd also be curious to hear that too. Thank you!
I need a working example.
I noticed this potential issue when looking at the source on a different occasion. I didn't need a class component myself, but this issue reveals it is indeed a problem.
@gilbarbara, Repros are often nice, but this issue seems pretty straightfoward. @man-of-seafood is defining a class component, and passing it to joyride like <Joyride tooltipComponent={MyClassComponent} />, and it's erroring.
As mentioned above, this source seems to be the culprit:
Line 85 assumes the provided component is a function. Can the following be used instead?
else {
const TooltipComponent = tooltipComponent;
component = <TooltipComponent {...renderProps} />;
}
It will still work the same for any function accepting props as a single argument, but also works for class components.
Most helpful comment
I noticed this potential issue when looking at the source on a different occasion. I didn't need a class component myself, but this issue reveals it is indeed a problem.
@gilbarbara, Repros are often nice, but this issue seems pretty straightfoward. @man-of-seafood is defining a class component, and passing it to joyride like
<Joyride tooltipComponent={MyClassComponent} />, and it's erroring.As mentioned above, this source seems to be the culprit:
https://github.com/gilbarbara/react-joyride/blob/f69dec61b1d87827cfe8ae4a1f3b3878c4c59c4a/src/components/Tooltip/index.js#L81-L86
Line 85 assumes the provided component is a function. Can the following be used instead?
It will still work the same for any function accepting props as a single argument, but also works for class components.