Código limpio con React: ¡Simple!

código limpio

Código limpio con React

Formas sencillas de escribir código limpio y mejor.


Código limpio

El código limpio es más que un código de trabajo. El código limpio es fácil de leer, fácil de entender y perfectamente organizado. En este artículo, veremos ocho formas en las que podemos escribir un código limpio de React.

Al analizar estas sugerencias, es importante recordar que eso es exactamente lo que son: sugerencias. Si no está de acuerdo con alguno de ellos, está bien. Sin embargo, estas son prácticas que he encontrado útiles para escribir códigos en React.

¡Vamos a sumergirnos!


1. Representación condicional solo para una condición

Si necesita renderizar algo de forma condicional cuando una condición es true y no renderizar nada cuando una condición es false, no utilice un operador ternario. En su lugar, utilice el operador &&.

Mal ejemplo:

import React, { useState } from 'react'

export const ConditionalRenderingWhenTrueBad = () => {
  const [showConditionalText, setShowConditionalText] = useState(false)

  const handleClick = () =>
    setShowConditionalText(showConditionalText => !showConditionalText)

  return (
    <div>
      <button onClick={handleClick}>Toggle the text</button>
      {showConditionalText ? <p>The condition must be true!</p> : null}
    </div>
  )
}

Buen ejemplo:

import React, { useState } from 'react'

export const ConditionalRenderingWhenTrueGood = () => {
  const [showConditionalText, setShowConditionalText] = useState(false)

  const handleClick = () =>
    setShowConditionalText(showConditionalText => !showConditionalText)

  return (
    <div>
      <button onClick={handleClick}>Toggle the text</button>
      {showConditionalText && <p>The condition must be true!</p>}
    </div>
  )
}

2. Representación condicional en cualquier condición

Si necesita renderizar condicionalmente una cosa cuando una condición es true y renderizar una cosa diferente cuando la condición es false, use un operador ternario.

Mal ejemplo:

import React, { useState } from 'react'

export const ConditionalRenderingBad = () => {
  const [showConditionOneText, setShowConditionOneText] = useState(false)

  const handleClick = () =>
    setShowConditionOneText(showConditionOneText => !showConditionOneText)

  return (
    <div>
      <button onClick={handleClick}>Toggle the text</button>
      {showConditionOneText && <p>The condition must be true!</p>}
      {!showConditionOneText && <p>The condition must be false!</p>}
    </div>
  )
}

Buen ejemplo:

import React, { useState } from 'react'

export const ConditionalRenderingGood = () => {
  const [showConditionOneText, setShowConditionOneText] = useState(false)

  const handleClick = () =>
    setShowConditionOneText(showConditionOneText => !showConditionOneText)

  return (
    <div>
      <button onClick={handleClick}>Toggle the text</button>
      {showConditionOneText ? (
        <p>The condition must be true!</p>
      ) : (
        <p>The condition must be false!</p>
      )}
    </div>
  )
}

3. Apoyos booleanos

Se puede proporcionar un prop verdadero a un componente con solo el nombre del prop sin un valor como este: myTruthyProp. Escribirlo como myTruthyProp={true} no es necesario.

Mal ejemplo:

import React from 'react'

const HungryMessage = ({ isHungry }) => (
  <span>{isHungry ? 'I am hungry' : 'I am full'}</span>
)

export const BooleanPropBad = () => (
  <div>
    <span>
      <b>This person is hungry: </b>
    </span>
    <HungryMessage isHungry={true} />
    <br />
    <span>
      <b>This person is full: </b>
    </span>
    <HungryMessage isHungry={false} />
  </div>
)

Buen ejemplo:

import React from 'react'

const HungryMessage = ({ isHungry }) => (
  <span>{isHungry ? 'I am hungry' : 'I am full'}</span>
)

export const BooleanPropGood = () => (
  <div>
    <span>
      <b>This person is hungry: </b>
    </span>
    <HungryMessage isHungry />
    <br />
    <span>
      <b>This person is full: </b>
    </span>
    <HungryMessage isHungry={false} />
  </div>
)

4. Puntales de cuerdas

Se puede proporcionar un valor de prop de cadena entre comillas dobles sin el uso de llaves o comillas inversas.

Mal ejemplo:

import React from 'react'

const Greeting = ({ personName }) => <p>Hi, {personName}!</p>

export const StringPropValuesBad = () => (
  <div>
    <Greeting personName={"John"} />
    <Greeting personName={'Matt'} />
    <Greeting personName={`Paul`} />
  </div>
)

Buen ejemplo:

import React from 'react'

const Greeting = ({ personName }) => <p>Hi, {personName}!</p>

export const StringPropValuesGood = () => (
  <div>
    <Greeting personName="John" />
    <Greeting personName="Matt" />
    <Greeting personName="Paul" />
  </div>
)

5. Funciones del controlador de eventos

Si un controlador de eventos solo toma un único argumento para el objeto de Event, puede proporcionar la función como el controlador de eventos de esta manera: onChange={handleChange}. No es necesario que envuelva la función en una función anónima como esta: onChange={e => handleChange(e)}.

Mal ejemplo:

import React, { useState } from 'react'

export const UnnecessaryAnonymousFunctionsBad = () => {
  const [inputValue, setInputValue] = useState('')

  const handleChange = e => {
    setInputValue(e.target.value)
  }

  return (
    <>
      <label htmlFor="name">Name: </label>
      <input id="name" value={inputValue} onChange={e => handleChange(e)} />
    </>
  )
}

Buen ejemplo:

import React, { useState } from 'react'

export const UnnecessaryAnonymousFunctionsGood = () => {
  const [inputValue, setInputValue] = useState('')

  const handleChange = e => {
    setInputValue(e.target.value)
  }

  return (
    <>
      <label htmlFor="name">Name: </label>
      <input id="name" value={inputValue} onChange={handleChange} />
    </>
  )
}

6. Pasar componentes como accesorios

Al pasar un componente como un accesorio a otro componente, no es necesario que envuelva este componente pasado en una función si el componente no acepta ningún accesorio.

Mal ejemplo:

import React from 'react'

const CircleIcon = () => (
  <svg height="100" width="100">
    <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
  </svg>
)

const ComponentThatAcceptsAnIcon = ({ IconComponent }) => (
  <div>
    <p>Below is the icon component prop I was given:</p>
    <IconComponent />
  </div>
)

export const UnnecessaryAnonymousFunctionComponentsBad = () => (
  <ComponentThatAcceptsAnIcon IconComponent={() => <CircleIcon />} />
)

Buen ejemplo:

import React from 'react'

const CircleIcon = () => (
  <svg height="100" width="100">
    <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
  </svg>
)

const ComponentThatAcceptsAnIcon = ({ IconComponent }) => (
  <div>
    <p>Below is the icon component prop I was given:</p>
    <IconComponent />
  </div>
)

export const UnnecessaryAnonymousFunctionComponentsGood = () => (
  <ComponentThatAcceptsAnIcon IconComponent={CircleIcon} />
)

7. Apoyos indefinidos

Los accesorios no definidos están excluidos, así que no se preocupe por proporcionar un respaldo undefined si está bien que el accesorio no esté definido.

Mal ejemplo:

import React from 'react'

const ButtonOne = ({ handleClick }) => (
  <button onClick={handleClick || undefined}>Click me</button>
)

const ButtonTwo = ({ handleClick }) => {
  const noop = () => {}

  return <button onClick={handleClick || noop}>Click me</button>
}

export const UndefinedPropsBad = () => (
  <div>
    <ButtonOne />
    <ButtonOne handleClick={() => alert('Clicked!')} />
    <ButtonTwo />
    <ButtonTwo handleClick={() => alert('Clicked!')} />
  </div>
)

Buen ejemplo:

import React from 'react'

const ButtonOne = ({ handleClick }) => (
  <button onClick={handleClick}>Click me</button>
)

export const UndefinedPropsGood = () => (
  <div>
    <ButtonOne />
    <ButtonOne handleClick={() => alert('Clicked!')} />
  </div>
)

8. Estado de configuración que se basa en el estado anterior

Establezca siempre el estado en función del estado anterior si el nuevo estado se basa en el estado anterior. Las actualizaciones de estado de React se pueden agrupar, y no escribir sus actualizaciones de esta manera puede generar resultados inesperados.

Mal ejemplo:

import React, { useState } from 'react'

export const PreviousStateBad = () => {
  const [isDisabled, setIsDisabled] = useState(false)

  const toggleButton = () => setIsDisabled(!isDisabled)

  const toggleButton2Times = () => {
    for (let i = 0; i < 2; i++) {
      toggleButton()
    }
  }

  return (
    <div>
      <button disabled={isDisabled}>
        I'm {isDisabled ? 'disabled' : 'enabled'}
      </button>
      <button onClick={toggleButton}>Toggle button state</button>
      <button onClick={toggleButton2Times}>Toggle button state 2 times</button>
    </div>
  )
}

Buen ejemplo:

import React, { useState } from 'react'

export const PreviousStateGood = () => {
  const [isDisabled, setIsDisabled] = useState(false)

  const toggleButton = () => setIsDisabled(isDisabled => !isDisabled)

  const toggleButton2Times = () => {
    for (let i = 0; i < 2; i++) {
      toggleButton()
    }
  }

  return (
    <div>
      <button disabled={isDisabled}>
        I'm {isDisabled ? 'disabled' : 'enabled'}
      </button>
      <button onClick={toggleButton}>Toggle button state</button>
      <button onClick={toggleButton2Times}>Toggle button state 2 times</button>
    </div>
  )
}

Menciones honoríficas

Las siguientes prácticas no son específicas de React, sino buenas prácticas para escribir código limpio en JavaScript (o cualquier lenguaje de programación, para el caso).

  • Extraiga lógica compleja en funciones claramente nombradas.
  • Extrae números mágicos en constantes.
  • Utilice variables con nombres claros.

¡Feliz codificación!

Recent Post