El componente cuadrado es un ejemplo de un contenedor simple . Sin embargo, no está limitado a sólo pasar a través de los componentes de los niños. Los niños (o cualquier otro accesorio) también puede ser una función que toma nuevos accesorios y devuelve elementos de React. De esta manera, el contenedor puede influir en el comportamiento de sus hijos de forma dinámica sin saber cuáles son sus hijos . Esto se conoce como un componente de puntal de renderizado.
Por ejemplo, actualmente, estamos ajustando el color de la hélice en línea dentro del método de representación.
Recordemos que la anotación del tipo React.FunctionComponent nos permitió acceder a la utilería de los niños de una manera muy tipificada. Si echamos un vistazo a las definiciones de los tipos, podemos ver que el accesorio infantil está escrito como:
1niños?:React.ReactNode
tipografía
El problema con esto es que ahora queremos pasar una función como el sostén de los niños. Esto está permitido en el JavaScript React de vainilla pero TypeScript arrojará un error si intentamos hacerlo usando el patrón de renderización del prop. Debemos aumentar las definiciones de tipo para cambiar como se escribe el atrezzo de los niños:
123456789interfaceSquareBackgroundProps{ x:número; y:número; niños:(props:SquareBackgroundChildrenProps):React.ReactElement<any;}interfaceSquareBackgroundChildrenProps{ backgroundColor: "red"|"black";}
tipografía
Aquí estamos declarando un puntal infantil explícito que es una función que toma nuevos puntales (SquareBackgroundChildrenProps) y devuelve un elemento de Reacción. TypeScript fusionará esta declaración de la interfaz con los tipos de React para que SquareBackgroundProps.children anule el tipo de puntal por defecto.
¿Por qué React.Element vs. React.ReactNode? La definición de React.FunctionComponent tiene un tipo de retorno de React.ReactElement, por lo que debemos hacer coincidir esa interfaz, de lo contrario TypeScript arrojará un error de tipo. Un componente funcional es más estricto de lo que permite React.ReactNode.
Podemos ir un paso más allá y utilizar tipos genéricos para crear una interfaz de ayuda para cualquier futuro componente de hélice:
123456789interfaceRenderProp<TChildrenProps,TElement=any;{(props:TChildrenProps):React.ReactElement<TElement;}interfaceSquareBackgroundProps{ x:número; y:número; children:RenderProp<{ backgroundColor: "red"|"black"};}
tipografía
La interfaz de RenderProp es una interfaz de función en TypeScript, denotada mediante el (…args): Anotación T.
Ahora que la definición se ha acortado, podemos simplificarla aún más eliminando la necesidad de una interfaz adicional y pasar la definición de objeto en línea a RenderProp en su lugar. También podemos añadir un valor genérico por defecto para TElement = any para proporcionar una comprobación de tipo opcional para el elemento React devuelto.
El componente de utilería SquareBackground render calculará el color de fondo de la utilería de los niños:
123456789constSquareBackground:React.FunctionComponent<SquareBackgroundPropsessmessment-;=props=;{if((props.y*BOARD_SIZE+ props.x)%2){retorno props.children({ backgroundColor: "negro"});}else{retorno props.children({ backgroundColor: "rojo"});}};
tipografía
Entonces reemplace el código existente con nuestro nuevo componente de renderización:
123456789{squares.map(col =;+ <SquareBackground key={`${col},${row}`} x={col} y={row};+ {({ backgroundColor }) ={;- <Square key={`${col},${row}`} color={(row * BOARD_SIZE + col) % 2 ? $0027red$0027 : $0027black$0027};+ <Square color={backgroundColor}}; {this.state.pieces[row * BOARD_SIZE + col]}+ </Square
diffEl componente SquareBackground encapsula ahora la lógica de la determinación del color, lo que hace que el código sea más fácil de leer y más fácil de probar. Aunque este ejemplo es simple, el patrón de representación del atrezzo es poderoso una vez que necesitas empezar a representar atrezzos o comportamientos más sofisticados.