React Day 3/40

AaksAaks
5 min read

Today I began by learning that in main.jsx, the <App /> is essentially a function component, and we can create other function components in a similar way.
I also encountered a few mistakes during this process. For example, although the function can work with a different syntax function() , it's considered a bad practice. Another issue I faced was that the component didn't render because I used a lowercase letter for the function's name.

In the custom library created yesterday, const reactElement {} was defined with type and props.

const reactElement = {
    type: 'a',
    props: {
        href: 'https://google.com',
        target: '_blank'
    },
    children: 'Click me to visit google'
}

Similarly, when a function component like newApp() is created, it is also converted into an object structure with properties such as type and props, much like the manually defined reactElement in the library.

function NewApp(){
  return (
  <div>
    <h1>I am from newApp</h1>
  </div>
  )
}

Exploring Render Functionality

If the reactElement from the custom library is copied and used directly, can it be rendered just like <App />?
No, because <App /> essentially calls App(), but reactElement is an object, so calling it in the same way <reactElement /> doesn't work. Even if correct syntax is used and capitalization of reactElement is changed to ReactElement, it still can't be called directly why?

The reason is important: In the custom library, a custom render function was implemented, but in this case, we don’t have custom rendering to render reactElement

Understanding Element Creation and Rendering

In a custom library, it was possible to define any custom structure, like type and props, and manually create and manage these elements.

In React, however, there’s a predefined structure for elements. When you use React.createElement(), it returns a React element (essentially a JavaScript object) that describes what should appear on the screen. React then takes care of rendering these elements to the DOM using its built-in render methods (like ReactDOM.render()).
Syntax of React.createElement():

  1. First Parameter: The type of the element (like a tag name or a component). It can be an HTML tag (e.g., p, h1)

    Example:

    • 'div' (for an HTML div tag)
  2. Second Parameter: An object that contains the properties (props) for the element. This could include attributes like href, className, id, or custom props.

    Example:

  3. Third Parameter: The children of the element, which could be text or other React elements. If there are no children, this can be null or undefined.

    Example:

    • 'Click me to visit Google' (for text content).

The key difference encountered between using our own custom library and React itself is in the rendering method.
In the custom library, a custom render function was implemented to handle elements.

In React, the built-in React.render() is used to handle the rendering process.

Injecting JavaScript Expressions

In React, JavaScript expressions (including variables, functions, or logic) can be injected directly into JSX using curly braces {}. The content inside the curly braces is treated as JavaScript.

Error:

const name = "Vite"
function NewApp(){
  return (
  <div>
    <h1>I am from newApp name</h1>
  </div>
  )
}

OUTPUT → I am from newApp name

Corrected:

const name = "Vite"
function NewApp(){
  return (
  <div>
    <h1>I am from newApp {name}</h1>
  </div>
  )
}

OUTPUT → I am from newApp Vite

Understanding Evaluated Expressions in React

In React, {name} inside JSX is known as an expression, and it’s an evaluated expression. This means that instead of writing full JavaScript code, you’re writing the final outcome of the code that React can evaluate. The key idea is that JSX only allows the result of JavaScript expressions inside the curly braces, not the entire logic.

Why Only the Final Evaluated Expression is Allowed?
When writing JSX, React expects the evaluation to already be done. The purpose of {} in JSX is to inject the result of an expression. For example:
If you tried to place a full JavaScript block or conditional logic directly inside the JSX, it wouldn't work because JSX expects the final value to render, not the logic itself.

Understanding by Going Back to the Library:
In the custom library created earlier, const reactElement = React.createElement('a', {href: '', target: ''}, text), we are manually creating an object structure for the element.

Now, what if {username} needs to be injected into this structure?

For variable injection like {username}, the entire React tree structure needs to be built first. This means the React tree must be fully evaluated before the final value of the variable (like {username}) can be placed into the text part of the element.

Only evaluated expressions (like variables or function results) can be injected into elements. Complex logic or full JavaScript blocks must be handled outside of JSX, and only their final results should be used in JSX.

Basic rule encountered today

ERROR→ JSX expressions must have one parent element.

createRoot(document.getElementById('root')).render(


    <NewApp />
    <App />


)

Corrected:

createRoot(document.getElementById('root')).render(

  <>
  <NewApp />
  <App />
  </>

)

In conclusion, today I learned about function components in React, including the importance of correct syntax for rendering elements. I discovered that while I can create elements as objects in a custom library, React requires its built-in rendering methods to display them correctly.

I also explored how to use evaluated expressions in JSX with curly braces, which allows for dynamic content. This highlighted the need to keep logic outside of JSX and reinforced the rule that JSX must have a single parent element. Overall, this experience clarified how React structures component creation and rendering.

1
Subscribe to my newsletter

Read articles from Aaks directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Aaks
Aaks