
Cree componentes agnósticos marco que sean realmente reutilizables e interoperables con todos los beneficios del ecosistema React, utilizando la API de elementos personalizados HTML5 para extender el vocabulario de HTML.
npm install react-standalone --save Eche un vistazo al componente mars-weather para obtener una idea sobre cómo estructurar su componente reutilizable, sin embargo, esencialmente un componente consiste en un nombre de etiqueta, como mars-weather , el component React y un esquema opcional que usa osom .
import { createModule } from 'standalone' ;
import schema from './schema' ;
import component from './component' ;
export default createModule ( 'mars-weather' , { schema , component } ) ; Una vez que haya creado su paquete, se creará un elemento personalizado con el tagName suministrado que se puede incrustar en el DOM: se invocarán todos los métodos de ciclo de vida react, como componentWillUnmount cuando el elemento se haya eliminado del DOM.
< mars-weather /> Como el componente mars-weather es un elemento completamente personalizado, se puede incrustar en cualquier marco de JavaScript: angular, vue, reaccionamiento, ciclo, emperadora, vainilla, etc. ...
Bonificación: Use Keo con límites de sombra para una verdadera sensación de polímero.
Al especificar los atributos en el elemento personalizado, los valores de los atributos se transmiten a su componente como accesorios: cualquier cambio en el state se manejará internamente en su componente, mientras que cualquier cambio en los atributos de su elemento causará un reiniciado con los props actualizados.
En el ejemplo de mars-weather , hemos configurado el método getDefaultProps para devolver los accesorios predeterminados, sin embargo, los usuarios pueden anular el PROP unit al pasar un atributo data llamado data-unit .
< mars-weather data-unit =" C " /> En el caso anterior, el atributo de data-unit se transformará en unit , ya que Standalone elimina cualquier prefijos data- , y luego vuelve a modificar su componente, lo que le permite acceder al atributo como this.props.unit .
Como todos los atributos HTML son string S, Standalone le permite especificar un esquema para su componente, que transformará los atributos string en el tipo de datos que espera usando osom .
export default {
unit : {
type : String ,
default : 'F'
}
} ; Una vez que haya configurado el esquema para usar para su componente, puede configurar felizmente el react propTypes habitual especificando el tipo de datos que espera pasar.
Usando eventos personalizados, puede configurar fácilmente un canal de comunicación entre sus componentes y el mundo exterior.
// Instantiate `CustomEvent` and then specify the name of the event, followed
// by the payload which will be passed to your listener function.
const event = new CustomEvent ( 'migrate-planets' , {
bubbles : true ,
detail : {
planet : 'Saturn'
}
} ) ;
findDOMNode ( this ) . dispatchEvent ( event ) ; Es crucial que emita el evento como bubbles: true lo contrario, de lo contrario, el evento simplemente se detendrá en el nodo findDOMNode(this) en lugar de burbujear hasta el nodo mars-weather , a menos que envíe el evento en el nodo mars-weather utilizando findDOMNode(this).parentNode .
Dentro de su componente, emite el evento, CustomEvent , usando dispatchEvent y luego ata su elemento personalizado, como mars-weather , usando addEventListener desde el exterior.
const node = document . querySelector ( 'mars-weather' ) ;
node . addEventListener ( 'migrate-planets' , event => {
// Update the `data-planet` attribute to reflect the newly migrated planet
// which will cause the component to re-render with the update prop.
node . setAttribute ( 'data-planet' , event . detail . planet ) ;
} ) ; Como invocar setAttribute en su componente hace que React reaccione para volver a renderizar su componente, puede ser útil suministrar una carga útil JSON a su componente, especialmente si está definiendo una multitud de atributos; Esto también ayuda con el rendimiento, ya que solo necesitaría un setAttribute para actualizar muchos accesorios y volver a renderizar.
Al definir un esquema, puede especificar un atributo que se analizará como JSON.
export default {
payload : {
type : JSON . parse
}
} Adjuntar una cadena JSON al atributo data-payload de su elemento hará que se analice en un objeto usando JSON.parse , y pase a su componente React como this.props.payload que se puede definir en las propTypes utilizando PropTypes.shape .
Todos los componentes Standalone extienden HTMLElement.prototype y permiten agregar funciones personalizadas al elemento, que puede invocar una vez que tenga una referencia al elemento asociado. Eche un vistazo a los métodos de mars-weather para un ejemplo.
const getWeather = function ( ) {
const weather = this . component . state . weather . atmoOpacity . toLowerCase ( ) ;
return `The current weather on Mars is ${ weather } !` ;
} ;
// ...
document . querySelector ( 'mars-weather' ) . getWeather ( ) ; Cuando un componente se ha agregado al DOM, actualizará su prototipo HTMLElement para asignar el componente renderizado para getPrototypeOf(this).component : esto convenientemente le permite acceder a los props y state , e invocar funciones internas al componente React.
Vale la pena señalar que this.component solo estará disponible una vez que el componente haya sido agregado al DOM.
Con la API de elementos personalizados es posible extender los elementos existentes: utilizando el atributo is para especializarse. Standalone le permite extender elementos pasando el elemento para extender.
// Creates a `mars-weather` element.
export default createModule ( 'mars-weather' , { schema , methods , component } ) ;
// Creates a `input[is="mars-weather"]` element.
export default createModule ( 'input/mars-weather' , { schema , methods , component } ) ; Vale la pena señalar que cuando extiende un elemento conocido, su elemento extenderá su prototipo: en el caso por encima del elemento mars-weather extenderá input y su prototipo HTMLInputElement .
* Requiere el excelente WebComponents-Lite.js Polyfill (13k Gzipped)