Home > Software design >  React typescript forwardref with defaultProps
React typescript forwardref with defaultProps

Time:10-22

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. enter image description here 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

CodePudding user response:

Brian Vaughn commmented on the issue of Stateless Component: React.forwardRef make defaultProps invalid

The function passed to forwardRef is not a React component. (React components don't accept a second ref param for example.) It's just a function that "renders" (returns) React elements. So it does not support defaultProps. 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

  • Related