React Clean Code – Simple ways to write better and cleaner Code

Clean code is more than just code that works. Clean code is easy to read, simple to understand, and organized. In this article, we introduce eight ways to write clean code for React.

This article is just a few suggestions, and if you don’t agree with them, it’s ok. These practices have helped me personally write React code. Let’s get started!

1. Conditional rendering with only one condition

In conditional rendering, if only something is rendered when the condition is true and nothing is rendered when the condition is false, do not use the trinary operator and use the && operator instead.

Bad example:

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>)}Copy the code

Good example:

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>)}Copy the code

2. Conditional rendering of two conditions

In conditional rendering, if you need to render one kind of content when the condition is true and another when the condition is false, use the ternary operator.

Bad example:

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>)}Copy the code

Good example:

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>)}Copy the code

3, Boolean props

When a component prop is true, you only need to provide the property name, for example, myTruthyProp, myTruthyProp={true} is not necessary.

Bad example:

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>
)
Copy the code

Good example:

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>
)
Copy the code

4, string props

String attribute values can be assigned in double quotes, without curly braces or back quotes.

Bad example:

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

Copy the code

Good example:

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>
)
Copy the code

5. Event handlers

If an Event handler accepts only an Event object, it can be used as an Event handler, like onChange={handleChange}, without wrapping the function in an anonymous function: OnChange = {e = > handleChange (e)}.

Bad example:

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)} />
    </>)}Copy the code

Good example:

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} />
    </>)}Copy the code

Pass the component as props

When a component is passed to another component as a prop, there is no need to wrap another layer with functions if the component being passed does not need additional props.

Bad example:

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 />} / >
)
Copy the code

Good example:

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} />
)
Copy the code

Undefined props

Undefined props are intercepted automatically, so don’t worry about undefined callbacks if undefined prop is allowed.

Bad example:

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>
)
Copy the code

Good example:

import React from 'react'

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

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

8. State assignment depends on the previous state

If the new state depends on the previous state, the previous state is taken as an argument and the state is assigned using the method of function assignment. React state updates are made in batches. If you do not write React state updates in batches, unexpected results may occur.

Bad example:

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>)}Copy the code

Good example:

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>)}Copy the code

Other practices

The following practices are not React specific, but good practices for writing clean code in JavaScript (and any programming language).

  • Extract complex logic into functions with clear names
  • Extract magic numbers as constants
  • Use explicitly named variables

Have fun coding!


Click the public account KooFE Front-end Team