DEV Community

Rick Delpo
Rick Delpo

Posted on • Updated on

I think I am having an "aha" moment about React, please confirm

It was not long ago that I struggled terribly over React. Then I gave up on it because it seemed too hard, way over my head and much overkill. I opted for Plain JS.

Someone used the term Spaghetti Code and told me that if I have many pages in my app that React would be useful. Then I read about reusable components in React. I have a Java background. It now seems that React is much like Java where we do subclassing. The next page inherits the behavior from a previous page.

Am I having an aha moment?

I think, for example, I can put some css or a listener in a component, then reuse the same on all my subsequent pages so I don't have to rewrite this code on each page (the spaghetti).

aha !!

PS: I also wrote a Dev article about my React Struggles here
https://dev.to/rickdelpo1/react-vs-plain-js-3cpk

Top comments (8)

Collapse
 
rickdelpo1 profile image
Rick Delpo

Thanks for the heads-up. I will research Composition, I totally don't get it yet.

Collapse
 
birdtho profile image
Christopher Thomas

Yeah, the power of react is keeping the document structure of the DOM tied to the relevant function code

In addition. Libraries like Recoil or Jotai are easier to use than Redux (which I won't touch. Because I don't want my head to hurt)

The library, styled-components solves another problem, by letting you put your CSS and styles in the same file with your JSX and JavaScript.

Learning to write hooks is nice too.

React makes a lot of things better but it's not perfect, and I could understand where it's easy to get side effects and bang your head. Try making small components and nesting everything together.

Collapse
 
rickdelpo1 profile image
Rick Delpo

Thanks for the answer Chris, but I need a first grade explanation. I got a bit lost reading ur comment.

Collapse
 
birdtho profile image
Christopher Thomas

Currently you know the basics of React:

function Component(props) {
  return (
    <div className="abc">
      <AnotherComponent />
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

And you would have in a CSS file

div.abc {
  width: 50px;
  height: 50px;
  ...
}
Enter fullscreen mode Exit fullscreen mode

With styled-components...

import React from 'react';
import styled from 'styled-components';

const ABCDiv = styled.div`
  width: 50px;
  height: 50px;
  ...
`;

function Component(props) {
  return (
    <ABCDiv>
      <AnotherComponent />
    </ABCDiv>
  );
}
Enter fullscreen mode Exit fullscreen mode

So you no longer have to split the style up or rely on inline style={{ width: '50px' }} attributes.

Now I don't want to try to talk about Redux, other than to say its a bit confusing and hard to get set up. (I didn't even try, it feels like putting my brain in a blender). Recoil and Jotai are similar, but they break up global state into pieces called atoms:

import { atom } from 'recoil';

interface Username {
  firstName: string;
  lastName: string;
}

export const UsernameAtom = atom<Username | null>({
  key: 'username',
  default: null,
});
Enter fullscreen mode Exit fullscreen mode

Then you can get or set this value from any component in the same way you would with a useState hook:

import React from 'react';
import { useRecoilState, useRecoilValue, useSetRecoilState} from 'recoil';
import { UsernameAtom } from './atoms';

export default function SomeComponent() {
  const setUsername = useSetRecoilState(UsernameAtom);
  - or -
  const username = useRecoilValue(UsernameAtom);
  - or -
  const [username, setUsername] = useRecoilState(UsernameAtom);

  return (
    <div>
      <span>My name is</span>
      { username !== null && (
        <p>
          {username.firstName} {username.lastName}
        </p>
      )}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

If you want to use reducers like redux has, you can use Recoil's selectors which essentially let you have one input value modify multiple recoil atoms at once. But in its most basic form, recoil is like globally available and share setState hooks.

So also, ReactJS is the best when you try to gather individual components to their own files. For instance, a dropdown box could be used for selecting from a menu on a restaurant website, but instead of just making a dropdown for that menu, you can make a dropdown which works for any menu or anything else. So now the dropdown and the data are no longer tied together. This is called decoupling.

function CoupledMenu() {
  const [menuItem, setMenuItem] = useRecoilState(SelectedMenuItemAtom);
  const menuItems = useRecoilValue(MenuItemsAtom);

  return (
    <div>
      <select onChange={(e) => setMenuItem(e.target.value)} selected={menuItem}>
        {menuItems && menuItems.map((item) => (
          <option key={`option_${item.value}_${item.label}`} value={item.value}>{item.label}</option>
        )}
      </select>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Uncouple from the data:

/**
 * JSDoc for explaining the required shape of the data input.
 * @param { values: { label?: string, value?: string}[], selected: string, setValue: (val: string) => void } props
 *
 */
function DecoupledMenu({ values, setValue, selected }) {
  return (
    <div>
      <select onChange={(e) => setValue(e.target.value)} selected={selected}>
        {values.map((item) => (
          <option key={`option_${item.value}_${item.label}`} value={item.value}>{item.label}</option>
        )}
      </select>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

There you have a component which just takes an array of objects with the { label: string, value: string } form and when a value is selected, calls setValue to set. In essence, the actual data is provided from outside the component, and it serves its duty as a dropdown field which you don't have to rewrite over and over.

To use:

function ParentComponent() {
  const [menuItem, setMenuItem] = useRecoilState(SelectedMenuItemAtom);
  const menuItems = useRecoilValue(MenuItemsAtom);

  return (
    <DecoupledMenu selected={menuItem} setValue={setMenuItem} values={menuItems} />
  );
}
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
rickdelpo1 profile image
Rick Delpo

thanks very much for the detail, guidance and ur time

Collapse
 
sabz profile image
Sabali

I was once in the same boat, then I came across Nextjs and everything started making sense. since I was coming from PHP background.

Collapse
 
rickdelpo1 profile image
Rick Delpo

yeah, I remember well the ole days using PHP and MySQL. This was way before Node JS came out. Thanks for the tip Sabali, I will start to research Next for my server side (I think this is the use case). Back in the days I used a java servlet on server side which, mixed with html tags, provided a client side rendering in addition to server side functions like connecting to data. I think what I am getting here is that Next.js gives us a modern day client rendering and still works server side. Am I correct about this? Also, Is it a replacement for PHP?

Collapse
 
sabz profile image
Sabali

You are correct, with the versatility of Nextjs I think its better than most PHP based frameworks or approaches.