I was trying to use defaultProps in functional component along with forwardRef, but was getting the error (refer screenshot).
I don't want to destructure the props in function params and assign default value. because got a lot of props in my original usecase.
I also tried assigning the default values JSON directly to ComponentA.defaultProps still same result.
How to resolve this ? Tried surfing but was not able to find any solution.
Also since we are using TS for type check, do we still need prototype JSON ?
#App.tsx
import './App.css';
import ComponentA from './components/A/A';
function App() {
return (
<div className="App">
<ComponentA>
<button>Button I am</button>
</ComponentA>
</div>
);
}
export default App;
#ComponentA.tsx
import React,{forwardRef} from "react"
import PropTypes from 'prop-types';
type Props = {
children:JSX.Element | JSX.Element[],
text:string,
text1?:string,
}
const ComponentA=(prop:Props)=>{
return <div>Hey
{prop.children}
{prop.text}
{prop.text1}
</div>
}
ComponentA.prototype = {
children:PropTypes.element.isRequired,
text:PropTypes.string.isRequired,
text1:PropTypes.string
}
ComponentA.defaultProps={
text: 'done'
} as Partial<Props>
export default forwardRef<HTMLAllCollection,Props>(ComponentA)
Thanks
Brian Vaughn commmented on the issue of Stateless Component: React.forwardRef make defaultProps invalid
The function passed to
forwardRefis not a React component. (React components don't accept a secondrefparam for example.) It's just a function that "renders" (returns) React elements. So it does not supportdefaultProps. We have tests that confirm this as expected behavior.React also logs the following error in the console (as can be seen in your Code Sandbox repro):
Warning: forwardRef render functions do not support propTypes or >defaultProps. Did you accidentally pass a React component?
That is the reason why you can not attach defaultProps before passing the function that "renders" to the forwordRef.
It's also mentioned in the type definitions of react:
// the input of ForwardedRef
interface ForwardRefRenderFunction<T, P = {}> {
(props: P, ref: ForwardedRef<T>): ReactElement | null;
displayName?: string | undefined;
// explicit rejected with `never` required due to
// https://github.com/microsoft/TypeScript/issues/36826
/**
* defaultProps are not supported on render functions
*/
defaultProps?: never | undefined;
/**
* propTypes are not supported on render functions
*/
propTypes?: never | undefined;
}
In your case just inverse the order of declarations:
import "./styles.css";
import { forwardRef } from "react";
import PropTypes from "prop-types";
type Props = {
children: JSX.Element | JSX.Element[];
// NOTE: text is optional since he has default value.
text?: string;
text1?: string;
};
const ComponentA = forwardRef<HTMLAllCollection, Props>((prop: Props) => {
return (
<div>
Hey
{prop.children}
{prop.text}
{prop.text1}
</div>
);
});
ComponentA.prototype = {
children: PropTypes.element.isRequired,
text: PropTypes.string,
text1: PropTypes.string
};
ComponentA.defaultProps = {
text: "done"
};
export default function App() {
return (
<ComponentA>
<button>Button I am</button>
</ComponentA>
);
}
Sandbox Code
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With