Why To Prefer JSX Over JSON-like Objects For Building React Components

Written by alexeychikk | Published 2020/12/18
Tech Story Tags: react | refactoring | jsx | javascript | code-quality | coding | design-patterns | react-components

TLDRvia the TL;DR App

Imagine you have several blocks of similar layout which are hard-coded on the frontend side. These blocks are not dynamic, they are not being fetched from back-end, it’s just a layout. Most beginners, when they see similar blocks of layout, start to think about arrays as a tool to handle similar stuff. So they often do something that is shown in the following snippet (the example might not be the best):
const cargoProperties = [
  { label: "Cargo type", content: "Containers, Grand Cube 40, Pallete" },
  { label: "Vehicle type", content: "Container Truck" },
  { label: "Size", content: "7 m" },
  { label: "Weight", content: "22kg/m3" },
  { label: "Qiantity", content: "5" },
  { label: "Dangerous", content: "no" },
  { label: "License plate", content: "#SR-045-JD" },
  {
    label: "Notes:",
    content: "Here you can see some notes from customer",
  },
];

const Layout = ({ styles }) => (
  <div>
    {cargoProperties.map((property) => (
      <RideProperty key={property.label} label={property.label}>
        {typeof property.content === "string" ? (
          <Text numberOfLines={1} style={styles.textProperty}>
            {property.content}
          </Text>
        ) : (
          <View style={styles.viewProperty}>{property.content}</View>
        )}
      </RideProperty>
    ))}
  </div>
);
What are the key problems of the code above?
  1. A part of layout itself is represented as a JSON-like object
    cargoProperties
    . JSX is much more expressive and readable than JSON and React gives us the power of JSX to code our layout so why not to use it to the fullest.
  2. Poor reusability because there is no React component created to encapsulate a single rendered item. Everything is just rendered straight under the
    .map().
  3. Poor readability because to understand what's rendered you need to visually find properties of a JSON-like structure in the elements/components tree. There are only two properties in each item of the list so now this may be easy for you. But when this object grows you will find yourself constantly switching between the object and the elements tree which is frustrating, takes time and is not fun at all.
  4. Rendering performance. React will rerender
    <Text>
    and
    <View>
    for each item in the list on each
    <Layout>
    update. This might not be an issue in the case above. But in the future this could be a performance bottleneck.

How would I refactor this code:

// `styles` prop comes from the HOC
const Row = ({ children, label, styles }) => (
  <RideProperty label={label}>
    {typeof children === "string" ? (
      <Text numberOfLines={1} style={styles.textProperty}>
        {children}
      </Text>
    ) : (
      <View style={styles.viewProperty}>{children}</View>
    )}
  </RideProperty>
);

const Layout = () => (
  <div>
    <Row label="Cargo type">Containers, Grand Cube 40, Pallete</Row>
    <Row label="Vehicle type">Container Truck</Row>
    <Row label="Size">7 m</Row>
    <Row label="Weight">22kg/m3</Row>
    <Row label="Qiantity">5</Row>
    <Row label="Dangerous">no</Row>
    <Row label="License plate">#SR-045-JD</Row>
    <Row label="Notes:">Here you can see some notes from customer</Row>
  </div>
);
What are the benefits of the solution above:
  1. The most important one is readability. A clean code is easy to read and understand. If you somehow don't find this more readable than the first snippet please write down why in the comments.
  2. It's reusable. You can reuse
    <Row>
    component now.
  3. Rendering performance of
    <Row>
    component can now be optimized using
    React.memo()
    or
    React.PureComponent
    .
  4. You can add event handlers individually to a particular
    <Row>
    you want.
Let me know how you would refactor it in the comments section.

Published by HackerNoon on 2020/12/18