← Home

πŸ’» React Component Tips

In this post I share some tips for how you can refactor your react components to be readable and declarative πŸ’£

Table of Contents

  1. Remove extra divs
  2. Remove unnecessary closing tags
  3. Use template literals instead of concatenation
  4. Destructure props
  5. Set defaults while destructuring
  6. Avoid verbose nullchecks
  7. Never use β€œvar”
  8. Use β€œconst” instead of β€œlet”
  9. Use the ternary operator

#1. Remove extra divs

Use <> (react fragment shorthand) if you just need an invisible container

❌ Instead of this:

const Component = () => {
  return (
    <div>
      <span>One</span>
      <span>Two</span>
      <span>Three</span>
    </div>
  );
};

βœ”οΈ Do this:

const Component = () => {
  return (
    <>
      <span>One</span>
      <span>Two</span>
      <span>Three</span>
    </>
  );
};

#2. Remove unnecessary closing tags

If an element does not have any children, a named closing tag is not required
Just close the element with /> instead

❌ Instead of this:

const Component = () => {
  return <Child foo={bar}></Child>;
};

βœ”οΈ Do this:

const Component = () => {
  return <Child foo={bar} />;
};

#3. Use template literals instead of concatenation

Avoid concatenating strings by using template literals instead

❌ Instead of this:

const Component = ({ classes }) => {
  return <div className={"bg-white " + classes} />;
};

βœ”οΈ Do this:

const Component = ({ classes }) => {
  return <div className={`bg-white ${classes}`} />;
};

#4. Destructure props

Destructure your props to eliminate repeating β€œprops.” throughout the component

❌ Instead of this:

const Component = (props) => {
  return (
    <div>
      <h1>{props.title}</h1>
      <span>{props.date}</span>
      <p>{props.description}</p>
    </div>
  );
};

βœ”οΈ Do this:

const Component = ({ title, date, description }) => {
  return (
    <div>
      <h1>{title}</h1>
      <span>{date}</span>
      <p>{description}</p>
    </div>
  );
};

You can destructure any variable within the function as well
Useful if you need to pass the entire props variable to a child

const Component = (props) => {
  const { title, date, description } = props;
  return (
    <div>
      <h1>{title}</h1>
      <span>{date}</span>
      <p>{description}</p>
      <Child {...props} />
      <OtherChild foobar={props} />
    </div>
  );
};

#5. Set defaults while destructuring

Avoid using imperative logic to redefine properties
Instead you can set a default value while destructuring

❌ Instead of this:

const Component = ({ propertyA }) => {
  let _propertyA = "default";
  if (propertyA !== undefined) {
    _propertyA = propertyA;
  }
  return <>{propertyA}</>; // returns "default" if propertyA is undefined
};

βœ”οΈ Do this:

const Component = ({ propertyA = "default" }) => {
  return <>{propertyA}</>; // returns "default" if propertyA is undefined
};

Note that null, false, and "" (empty string) would all be valid inputs for propertyA and would bypass the default. See Avoid verbose nullchecks for how to solve this

#6. Avoid verbose nullchecks

undefined and null are considered β€œfalsy” by JavaScript.
You can check that a property is not falsy using the logical AND operator (&&)

❌ Instead of this:

const Component = ({ propertyA }) => {
  let propertyAIsValid = false;
  if (propertyA !== undefined && propertyA !== null && propertyA !== "") {
    propertyAIsValid = true;
  }
  return propertyAIsValid ? <>Yep it's valid!</> : <>Invalid propertyA</>;
};

βœ”οΈ Do this:

const Component = ({ propertyA }) => {
  return propertyA && propertyA !== "" ? (
    <>Yep it's valid!</>
  ) : (
    <>Invalid propertyA</>
  );
};

#7. Never use β€œvar”

From stackoverflow:

var is on ES6 for legacy reasons. In theory, the let statement is better since it behaves more predictably on block scopes, but it won’t work with more outdated interpreters. So, if you’re coding with only ES6 in mind, go for let.

#8. Use β€œconst” instead of β€œlet”

β€œconst” defines a constant that can’t be changed later
”let” defines a variable that can be changed later

If you find yourself needing to use β€œlet”, you might be trying to create imperative logic.
Try to rethink the problem and define once using β€œconst”

❌ Instead of this:

const Component = ({ size }) => {
  let className = "bg-white accent-bottom-primary";

  if (size === "large") {
    className = className + " large";
  } else if (size === "small") {
    className = className + " small";
  }

  return <div className={className} />;
};

βœ”οΈ Do this:

const Component = ({ size }) => {
  const className = `bg-white accent-bottom-primary${size ? ` ${size}` : ""}`;
  return <div className={className} />;
};

#9. Use the ternary operator

The ternary operator shortens your if statement logic and makes your code read a bit like a spoken question

condition ? evaluates if true : evaluates if false
”Are we loading ? yes, so show < Loading /> : no, so show < Done />”

❌ Instead of this:

const Component = ({ loading }) => {
  if (loading) {
    return <Loading />;
  } else {
    return <Done />;
  }
};

βœ”οΈ Do this:

const Component = ({ loading }) => {
  return loading ? <Loading /> : <Done />;
};

You can nest multiple ternary operators for more complex conditions

const Component = ({ loading, data, error }) => {
  const empty = !data || data.length === 0;

  return loading ? (
    <div>Loading</div>
  ) : empty ? (
    <div>Data is empty</div>
  ) : error ? (
    <div>There was an error</div>
  ) : (
    <div>Your data is: {data}</div>
  );
};

Thanks for reading πŸ˜ƒ

← Home