Escrevendo uma API para componentes de reação, parte 2: dê nomes ao comportamento, não à interação

Escrevendo uma API para componentes React, parte 1: não crie objetos conflitantes

Escrevendo uma API para componentes de reação, parte 2: dê nomes ao comportamento, não à interação

Escrevendo uma API para componentes React, parte 3: a ordem dos adereços é importante

Escrevendo uma API para reagir componentes, parte 4: Cuidado com o Apropacalypse!

Escrevendo uma API para reagir componentes, parte 5: apenas usar composição

Escrevemos API para componentes React, parte 6: criamos comunicação entre componentes

Temos um componente switch - Switch , que aceita prop, vamos chamá-lo de something enquanto.


Um desenvolvedor que usa nosso componente pode passar uma função, e a chamaremos quando o valor for alterado.


mudar


 <Switch something={fn} /> 

O React nos dá a capacidade de chamar prop conforme gostamos: handler / clickHandler / onClick / onToggle , etc.


A convenção de que o nome do manipulador de eventos deve começar com on , por exemplo, onClick , onClick . Isso ocorre porque a especificação HTML possui muitos manipuladores que já seguem esta convenção: onkeydown , onchange , onclick etc.


Reutilizar um contrato existente é uma ótima idéia; os desenvolvedores não precisarão se lembrar de algo novo.


OK, e o onClick ?


 <Switch onClick={fn} /> 

Aqui não sou defensor do nome onClick , esse nome sugere que um clique do mouse é a única maneira de interagir com esse componente.


Os usuários de um dispositivo móvel podem pressionar o botão com um dedo ou arrastá-lo para a direita. Usuários com deficiência visual podem usá-lo com o software leitor de tela e usar as teclas do teclado.


Como desenvolvedor que usa esse componente, não quero pensar em como os usuários finais interagem com esse componente. Eu só quero anexar uma função que é chamada quando o valor muda.


Dê nomes para sua API que não indicarão uma maneira de interagir:


 <Switch onToggle={fn} /> 

Isso faz sentido, certo? Alterne (alterna) entre dois valores.


Dentro de um componente, convém proxy todas as interações possíveis na mesma função


 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) }} /> ) } 

Levamos em conta todas as opções para fornecer uma API clara aos nossos usuários (desenvolvedores).


Agora vamos falar sobre o componente de entrada de texto.


entrada


 <TextInput /> 

O HTML tem um atributo onchange , a documentação do React usa o onChange em seus exemplos. Aparentemente, existe um consenso sobre essa pontuação.


 <TextInput onChange={fn} /> 

Muito simples


Agora vamos colocar esses dois componentes lado a lado.


juntos


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

Viu algo estranho?


Apesar do fato de que ambos os componentes requerem o mesmo comportamento, prop é chamado de maneira diferente. Esses acessórios são perfeitos para seus respectivos componentes, mas quando você olha para os componentes juntos, parece bastante controverso.


Um desenvolvedor que usará esses componentes sempre precisará verificar o nome do suporte antes de usá-lo.


Então, aqui está a dica 2: lute por adereços consistentes entre os componentes . O mesmo comportamento deve ter o mesmo suporte para todos os componentes.


Este conselho também pode ser formulado da seguinte maneira: Procure uma área mínima da API . Você deve limitar o número de APIs que um desenvolvedor deve dominar antes de poder trabalhar produtivamente.


Quero dizer que todos os méritos deste tópico são de Sebastian Markbåge . (Sua apresentação: Área de superfície mínima da API )


A maneira de implementar esse conselho é escolher um suporte e usá-lo em todos os seus componentes. Dos dois adereços que temos em nosso exemplo, o onChange também onChange na especificação HTML, portanto alguns desenvolvedores podem reconhecê-lo.


juntos


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

A consistência entre os componentes e, como resultado, a simplicidade de aprender sua API supera a escolha do suporte "ideal" para um único componente.




Um pequeno bônus.


Vamos falar sobre a assinatura desta função.


 <TextInput onChange={fn} /> 

O onChange eventos onChange ( fn neste exemplo) recebe um argumento - event .


Funciona com todas as alterações. Você pode obter várias informações úteis deste evento.


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

Provavelmente, a maioria dos desenvolvedores estará interessada em event.target.value para que eles possam usá-lo para outras tarefas - usar no estado, enviar formulário etc.


No caso do nosso componente Switch , cada ação representa um "evento" separado - event . Este event terá propriedades diferentes para clicar e arrastar. Como garantimos que a API seja consistente?


Podemos definir 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/pt459378/


All Articles