renderizar react qué que practicas permite nos método mejores etiquetas estados ejemplos diferentes componentes componentdidmount reactjs typescript tsx

reactjs - qué - Valor de propiedad predeterminado en React componente usando TypeScript



react js ejemplos (5)

Accesorios predeterminados con componente de clase

El uso de static defaultProps es correcto. También debe usar interfaces, no clases, para los accesorios y el estado.

Actualización 2018/12/1 : TypeScript ha mejorado la verificación de tipos relacionada con defaultProps a defaultProps largo del tiempo. Siga leyendo para conocer el uso más reciente y mejor hasta usos y problemas más antiguos.

Para TypeScript 3.0 y superior

TypeScript agregó específicamente soporte para defaultProps para hacer que la verificación de tipos funcione como es de esperar. Ejemplo:

interface PageProps { foo: string; bar: string; } export class PageComponent extends React.Component<PageProps, {}> { public static defaultProps = { foo: "default" }; public render(): JSX.Element { return ( <span>Hello, { this.props.foo.toUpperCase() }</span> ); } }

Que se puede procesar y compilar sin pasar un atributo foo :

<PageComponent bar={ "hello" } />

Tenga en cuenta que:

  • foo no está marcado como opcional (es decir, foo?: string ) aunque no se requiere como un atributo JSX. Marcar como opcional significaría que podría estar undefined , pero en realidad nunca estará undefined porque defaultProps proporciona un valor predeterminado. Piénselo de forma similar a cómo puede marcar un parámetro de función opcional, o con un valor predeterminado, pero no ambos, pero ambos significan que la llamada no necesita especificar un valor . TypeScript 3.0+ trata defaultProps de manera similar, ¡lo cual es realmente genial para los usuarios de React!
  • defaultProps no tiene una anotación de tipo explícito. Su tipo es inferido y utilizado por el compilador para determinar qué atributos JSX son necesarios. Puede usar defaultProps: Pick<PageProps, "foo"> para asegurarse de que defaultProps coincida con un subconjunto de PageProps . Más sobre esta advertencia se explica aquí .
  • Esto requiere @types/react versión 16.4.11 para funcionar correctamente.

Para TypeScript 2.1 hasta 3.0

Antes de que TypeScript 3.0 implementara la compatibilidad con el compilador para defaultProps , todavía podía usarlo, y funcionaba al 100% con React en tiempo de ejecución, pero dado que TypeScript solo consideraba los accesorios al verificar los atributos JSX, tendría que marcar los accesorios que tienen valores predeterminados como opcionales con ? . Ejemplo:

interface PageProps { foo?: string; bar: number; } export class PageComponent extends React.Component<PageProps, {}> { public static defaultProps: Partial<PageProps> = { foo: "default" }; public render(): JSX.Element { return ( <span>Hello, world</span> ); } }

Tenga en cuenta que:

  • Es una buena idea anotar defaultProps con Partial<> para que compruebe los tipos con sus accesorios, pero no tiene que proporcionar a cada propiedad requerida un valor predeterminado, lo que no tiene sentido ya que las propiedades requeridas nunca deberían necesitar un valor predeterminado.
  • Cuando se utiliza strictNullChecks el valor de this.props.foo possibly undefined estará possibly undefined y requerirá una aserción no nula (es decir, this.props.foo! ) O type-guard (es decir, if (this.props.foo) ... ) para eliminar undefined Esto es molesto ya que el valor de apoyo predeterminado significa que en realidad nunca será indefinido, pero TS no entendió este flujo. Esa es una de las razones principales por las que TS 3.0 agregó soporte explícito para defaultProps .

Antes de TypeScript 2.1

Esto funciona igual pero no tiene tipos Partial , por lo tanto, omita Partial<> y proporcione los valores predeterminados para todos los accesorios necesarios (aunque esos valores predeterminados nunca se usarán) u omita la anotación de tipo explícito por completo.

Accesorios predeterminados con componentes funcionales

También puede usar defaultProps en los componentes de la función, pero debe escribir su función en la interfaz StatelessComponent ( FunctionComponent en @types/react versión 16.7.2 +) para que TypeScript conozca defaultProps en la función:

interface PageProps { foo?: string; bar: number; } const PageComponent: StatelessComponent<PageProps> = (props) => { return ( <span>Hello, {props.foo}, {props.bar}</span> ); }; PageComponent.defaultProps = { foo: "default" };

Tenga en cuenta que no tiene que usar Partial<PageProps> ningún lugar porque StatelessComponent.defaultProps ya está especificado como parcial en TS 2.1+.

Otra buena alternativa (esto es lo que uso) es desestructurar los parámetros de sus props y asignar valores predeterminados directamente:

const PageComponent: StatelessComponent<PageProps> = ({foo = "default", bar}) => { return ( <span>Hello, {foo}, {bar}</span> ); };

¡Entonces no necesitas los defaultProps en absoluto! Tenga en cuenta que si proporciona defaultProps en un componente de función, tendrá prioridad sobre los valores de parámetros predeterminados, porque React siempre pasará explícitamente los valores de defaultProps (por lo que los parámetros nunca están indefinidos, por lo tanto, el parámetro predeterminado nunca se usa). d usar uno u otro, no ambos.

No puedo encontrar la manera de establecer valores de propiedad predeterminados para mis componentes usando Typecript.

Este es el código fuente:

class PageState { } export class PageProps { foo: string = "bar"; } export class PageComponent extends React.Component<PageProps, PageState> { public render(): JSX.Element { return ( <span>Hello, world</span> ); } }

Y cuando trato de usar el componente así:

ReactDOM.render(<PageComponent />, document.getElementById("page"));

Me sale un error diciendo que falta la propiedad foo . Quiero usar el valor predeterminado. También he intentado usar static defaultProps = ... dentro del componente, pero no tuvo ningún efecto, como sospechaba.

src/typescript/main.tsx(8,17): error TS2324: Property ''foo'' is missing in type ''IntrinsicAttributes & IntrinsicClassAttributes<PageComponent> & PageProps & { children?: ReactEle...''.

¿Cómo puedo usar los valores de propiedad predeterminados? Muchos componentes de JS que usa mi compañía dependen de ellos y no usarlos no es una opción.


Con Typecript 2.1+, use Parcial <T> en lugar de hacer que las propiedades de su interfaz sean opcionales.

export interface Props { obj: Model, a: boolean b: boolean } public static defaultProps: Partial<Props> = { a: true };


Con Typecript 3.0 hay una nueva solución para este problema:

export interface Props { name: string; } export class Greet extends React.Component<Props> { render() { const { name } = this.props; return <div>Hello ${name.toUpperCase()}!</div>; } static defaultProps = { name: "world"}; } // Type-checks! No type assertions needed! let el = <Greet />

Tenga en cuenta que para que esto funcione, necesita una versión más nueva de @types/react que 16.4.6 . Funciona con 16.4.11 .


De un comentario de @pamelus sobre la respuesta aceptada:

Debe hacer que todas las propiedades de la interfaz sean opcionales (incorrectas) o especificar el valor predeterminado también para todos los campos obligatorios (repetitivo innecesario) o evitar especificar el tipo en defaultProps.

En realidad, puede usar la herencia de interfaz de Typecript . El código resultante es solo un poco más detallado.

interface OptionalGoogleAdsProps { format?: string; className?: string; style?: any; scriptSrc?: string } interface GoogleAdsProps extends OptionalGoogleAdsProps { client: string; slot: string; } /** * Inspired by https://github.com/wonism/react-google-ads/blob/master/src/google-ads.js */ export default class GoogleAds extends React.Component<GoogleAdsProps, void> { public static defaultProps: OptionalGoogleAdsProps = { format: "auto", style: { display: ''block'' }, scriptSrc: "//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js" };


Para aquellos que tienen accesorios opcionales que necesitan valores predeterminados. Crédito aquí :)

interface Props { firstName: string; lastName?: string; } interface DefaultProps { lastName: string; } type PropsWithDefaults = Props & DefaultProps; export class User extends React.Component<Props> { public static defaultProps: DefaultProps = { lastName: ''None'', } public render () { const { firstName, lastName } = this.props as PropsWithDefaults; return ( <div>{firstName} {lastName}</div> ) } }