React typescript forwardref with defaultProps

xwbd5t1u  于 2023-05-01  发布在  TypeScript
关注(0)|答案(2)|浏览(126)

我试图在函数组件中使用defaultProps和forwardRef,但是得到了错误(参考屏幕截图)。
我不想分解函数参数中的 prop 并分配默认值。因为在我原来的用例中得到了很多 prop 。我还尝试将默认值JSON直接分配给ComponentA。defaultProps仍然是相同的结果。

如何解决这个问题?我试过冲浪,但找不到任何解决方案。同样,由于我们使用TS进行类型检查,我们仍然需要原型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.土耳其电信公司

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)

谢谢

mv1qrgav

mv1qrgav1#

Brian Vaughn关于Stateless Component: React.forwardRef make defaultProps invalid问题的评论
传递给forwardRef的函数不是React组件。(例如,React组件不接受第二个ref参数。)它只是一个“呈现”(返回)React元素的函数。不支持defaultProps。我们有测试证实这是预期的行为。
React还在控制台中记录以下错误(可以在Code Sandbox repro中看到):
警告:forwardRef呈现函数不支持propTypes或〉defaultProps。你是否意外传递了React组件?
这就是为什么在将function that "renders"传递到forwordRef之前不能附加defaultProps的原因。
在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;
}

在你的例子中,只需颠倒声明的顺序:

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

7dl7o3gd

7dl7o3gd2#

2023年更新

Default Props are deprecated。对于功能性组件,最好在解构props时指定默认值。此外,在使用TypeScript时,您真的不需要PropTypes。TypeScript已经为您提供了严格的类型化。

import "./styles.css";
import { forwardRef } from "react";

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>(
  ({ children, text = "done", text1 }: Props) => {
    return (
      <div>
        Hey
        {children}
        {text}
        {text1}
      </div>
    );
  }
);

export default function App() {
  return (
    <ComponentA>
      <button>Button I am</button>
    </ComponentA>
  );
}

Code Sandbox Link

相关问题