Escribir una API para React Components, Parte 2: Dar nombres al comportamiento, no a la interacción

Escribir una API para componentes React, parte 1: no cree accesorios conflictivos

Escribir una API para React Components, Parte 2: Dar nombres al comportamiento, no a la interacción

Escribir una API para componentes React, parte 3: el orden de los accesorios es importante

Escribir una API para React Components, Parte 4: ¡Cuidado con el Apropacalypse!

Escribir una API para React Components, Parte 5: solo use la composición

Escribimos API para componentes React, parte 6: creamos comunicación entre componentes

Tenemos un componente de switch: Switch , que acepta prop, llamémoslo something ahora.


Un desarrollador que usa nuestro componente puede pasar una función, y la llamaremos cuando cambie el valor.


cambiar


 <Switch something={fn} /> 

React nos da la capacidad de llamar a prop como nos gusta: handler / clickHandler / onClick / onToggle , etc.


La convención de que el nombre del controlador de eventos debería comenzar con on , por ejemplo, onClick , se onClick . Esto se debe a que la especificación HTML tiene muchos controladores que ya siguen esta convención: onkeydown , onchange , onclick , etc.


Reutilizar un acuerdo existente es una gran idea; los desarrolladores no tendrán que recordar algo nuevo.


OK, ¿qué hay de onClick ?


 <Switch onClick={fn} /> 

Aquí no soy partidario del nombre onClick , tal nombre sugiere que un clic del mouse es la única forma de interactuar con este componente.


Los usuarios de un dispositivo móvil pueden presionar el interruptor con un dedo o arrastrarlo hacia la derecha. Los usuarios con discapacidad visual pueden usarlo con el software lector de pantalla y usar las teclas del teclado.


Como desarrollador que usa este componente, no quiero pensar en cómo los usuarios finales interactúan con este componente. Solo quiero adjuntar una función que se llama cuando cambia el valor.


Dé nombres para su API que no indiquen una forma de interactuar:


 <Switch onToggle={fn} /> 

Eso tiene sentido, ¿verdad? toggles palanca (alterna) entre dos valores.


Dentro de un componente, es posible que desee proxy todas las interacciones posibles en la misma función


 function Switch(props) { return ( <div className="switch" /*      */ onClick={props.onToggle} onKeyDown={function(event) { /*   enter  ,  event  */ if (event.key === 'Enter') props.onToggle(event) }} onDrag={function(event) { /*   */ if (event.toElement === rightSide) props.onToggle(event) }} /> ) } 

Tomamos en cuenta todas las opciones para dar una API clara a nuestros usuarios (desarrolladores).


Ahora hablemos sobre el componente de entrada de texto.


entrada


 <TextInput /> 

HTML tiene un atributo onchange , la documentación de React utiliza onChange en sus ejemplos. Aparentemente, hay un consenso sobre este puntaje.


 <TextInput onChange={fn} /> 

Muy simple


Ahora pongamos ambos componentes uno al lado del otro.


juntos


 <TextInput onChange={fn} /> <Switch onToggle={fn} /> 

¿Ves algo extraño?


A pesar de que ambos componentes requieren el mismo comportamiento, prop se llama de manera diferente. Estos accesorios son perfectos para sus respectivos componentes, pero cuando miras tus componentes juntos, parece bastante controvertido.


Un desarrollador que usará estos componentes siempre tendrá que verificar el nombre del accesorio antes de usarlo.


Así que aquí está el consejo # 2: luchar por apoyos consistentes entre los componentes . El mismo comportamiento debe tener el mismo accesorio para todos los componentes.


Este consejo también se puede formular de la siguiente manera: Esforzarse por un área mínima de API . Debe limitar el número de API que un desarrollador debe dominar antes de que pueda trabajar productivamente.


Quiero decir que todos los méritos sobre este tema van a Sebastian Markbåge . (Su presentación: Área de superficie API mínima )


La forma de implementar este consejo es elegir un accesorio y usarlo en todos sus componentes. De los dos accesorios que tenemos en nuestro ejemplo, onChange también onChange en la especificación HTML, por lo que algunos desarrolladores pueden reconocerlo.


juntos


 <TextInput onChange={fn} /> <Switch onChange={fn} /> <Select onChange={fn} /> // etc. 

La consistencia entre los componentes y, como resultado, la simplicidad de aprender su API, supera la elección del accesorio "ideal" para un componente individual.




Un pequeño bono.


Hablemos de la firma de esta función.


 <TextInput onChange={fn} /> 

El onChange eventos onChange ( fn en este ejemplo) recibe un argumento: event .


Funciona con cada cambio. Puede obtener un montón de información útil de este evento.


 function fn(event) { console.log(event.target) //   console.log(event.target.value) //     console.log(event.which) //      } 

Lo más probable es que la mayoría de los desarrolladores estén interesados ​​en event.target.value , para que puedan usarlo para otras tareas: usar en estado, enviar formulario, etc.


En el caso de nuestro componente Switch , cada acción representa un "evento" separado - event . Este event tendrá diferentes propiedades para hacer clic y arrastrar. ¿Cómo nos aseguramos de que la API sea coherente?


Podemos establecer manualmente event.target.value para cada "evento":


 function Switch(props) { /*  */ const fireHandler = event => { const newValue = !oldValue /*  ,     : */ event.target.value = newValue /*     */ props.onChange(event) } return ( <div className="switch" /*      */ onClick={fireHandler} onKeyDown={function(event) { if (event.key === 'Enter') fireHandler(event) }} onDrag={function(event) { if (event.toElement === rightSide) fireHandler(event) }} /> ) } 

Source: https://habr.com/ru/post/459378/


All Articles