Ada-Online-2da-Gen / Todo-App-Angie

1 stars 0 forks source link

Convención: nombres de event handlers #6

Open pabloHoc opened 4 years ago

pabloHoc commented 4 years ago

Descripción de la situación

Para evitar futuros conflictos y tener una convención que nos evite tener que estar pensando buenos nombres, a la hora de definir props que sean eventos y necesiten de un callback, vamos a usar lo siguiente:

Convención

onEvent onSubjectEvent

es decir, el prefijo on- más el nombre del evento, y en caso de que sea necesario, sobre qué se hace el evento (por ejemplo, cuando hay dos eventos iguales sobre distintos componentes).

Ejemplos

onClick onDeleteIconClick onTextInputChange onEditIconClick

Las funciones que actúen como callbacks de dichos eventos (los event handlers) se escriben:

Convención

handleEvent handleSubjectEvent

de la misma manera que los eventos, excepto que utilizan el prefijo handle-

Ejemplos

handleClick handleDeleteIconClick handleTextInputChange handleEditIconClick

Otras situaciones

Cuando un handler necesita invocar a otro handler (para no repetir código), se extrae en una nueva función el código que se necesita y se la invoca desde ambos handlers. Nunca se invoca un handler desde otro.

pabloHoc commented 4 years ago

Ejemplo de refactorización. Supongamos que tenemos lo siguiente:

  const saveChangesEnter = (event) => {
    if (event.key === 'Enter' && todoText.length > 0) {
      onUpdateText(id, todoText)
      setEditing(false)
    }
  }

  const saveChangesBtn = () => {
    if (todoText.length > 0) {
      onUpdateText(id, todoText)
      setEditing(false)
    }
  }

return (
  <Input
    onKeyPress={saveChangesEnter}
  />
  <Button onClick={saveChangesBtn}>Guardar</Button>
)

Si cambiamos los nombres de los event handlers según a convención nos quedaría así:

  const handleKeyPress = (event) => {
    if (event.key === 'Enter' && todoText.length > 0) {
      onUpdateText(id, todoText)
      setEditing(false)
    }
  }

  const handleSaveButtonClick = () => {
    if (todoText.length > 0) {
      onUpdateText(id, todoText)
      setEditing(false)
    }
  }

return (
  <Input
    onKeyPress={handleKeyPress}
  />
  <Button onClick={handleSaveButtonClick}>Guardar</Button>
)

En este caso, usamos handleSaveButtonClick porque hay otros eventos de click (que acá no los puse). Ahora en ambos casos tenemos código repetido, por lo que podemos extraerlo en una nueva función:

 const finishTodoEdition = () => {
    if (todoText.length > 0) {
      onUpdateText(id, todoText)
      setEditing(false)
    }
 }

  const handleKeyPress = (event) => {
    if (event.key === 'Enter') {
      finishTodoEdition()
    }
  }

  const handleSaveButtonClick = () => {
    finishTodoEdition()
  }

return (
  <Input
    onKeyPress={handleKeyPress}
  />
  <Button onClick={handleSaveButtonClick}>Guardar</Button>
)
pabloHoc commented 4 years ago

Por otro lado, en componentes con eventos más "custom", pongamos un todo, tendríamos algo como:

<Todo onUpdateText={handleUpdateText} onDelete={handleDelete} /> 

En caso (probable) de que luego tengamos varias cosas por eliminar, podríamos definir el sujeto:

<Todo onUpdateText={handleUpdateText} onDelete={handleDeleteTodo} />