Convert and Execute JS code as React Component
Tags: react, javascript
Published: 2022-12-08 14:12:35

Before going any further know that this post consist of two part: **Why do this?** and **How do this?**
Since i am writing this post as an supplementary post of my other post ([NextJS - Access window and localStorage](https://dev.to/ariyou2000/nextjs-access-window-and-localstorage-10i3)) i'm going to first explain **How** and then **Why**

---

## How
Create a component that contains only logic and return no `JSX`. In other word all logic and no view(UI):

Following example will log a message in console when it's called

```jsx
const ConsoleLogger = () => {
  console.log("Hello World");
  return null; // return value must be JSX (our UI or view) that is null.
};

export default ConsoleLogger;

```

You can even pass a message to print:
```jsx
const ConsoleLogger = ({massage}) => {
  console.log(massage);
  return null; // return value must be JSX (our UI or view) that is null.
};

export default ConsoleLogger;

```

Now lets take it a step further and take advantage of react features such as `useEffect` hook and do some practical things.

Following example shows how to subscribe an `EventListener` to our browser `window` object:
```jsx
// components/Scroll.js

import { useEffect } from "react";

const Scroll = () => {

  useEffect(() => {
    indow.addEventListener("scroll", () => { console.log("scroll!"); });
  }, []); // empty dependencies array means "run this once on first mount"

  return null; // it render nothing in page and only runs logics
};

export default Scroll;
```
Now need to add this component to your `React Component Tree`

```jsx
// pages/index.js

import Scroll from "../components/Scroll";

const Home = () => (
  <div style={{ minHeight: "1000px" }}>
    <h1>Home</h1>
    <Scroll />
    <ConsoleLogger massage="Hello World" />
  </div>
);

export default Home;
```
**Note:** We used `useEffect` hook because some time (e.g. using Frameworks such as Next.JS and `SSR` (Server-Side Rendering)) you do not have access to `document` or `window` properties such as `local storage` ([Read more here!](https://dev.to/ariyou2000/nextjs-access-window-and-localstorage-10i3)). And you need to run such a code in run-time(rendering phase) and `useEffect` hook will do so.

---

## Why
There are instance that you need to run an `JavaScript` statement that rely on `React` features.
You might wondering why you need to change your code and not just using it in relevant components? 
But what if there is no logical relation between them? For example Subscribing(registering) an `EventListener` such as a "Scroll" event to your `window` object?

As you can see this is not relevant to any component and it's a operation that apply globally with no dependency.

Or in some instance you want to simple change the way your code looks (calling it like React Components instead of calling a function)
```jsx
const Home = () => (
  <div>
    <h1>Home</h1>

    <SubToScroll /> vs {SubToScroll()}

  </div>
);

export default Home;
```


**Note: Make JavaScript logic Independent to components**
`useEffect` is a hook and it must be used in functional components.
But at the same time, it's wrong for our JS codes that are unrelated to a specific component to depend on them.
And it's also wrong to have duplicated statements all over our code.
So we have two options:

1. Create global functions and export them.
2. turn our initial JavaScript file into a true React component

Solution `No. 1` is simple and it has its own downsides such as being unable to use or hard implementation of react hooks and etc.
So we recommend running your JS logical code as a react component.