ReactJS - React Without JSX

What is JSX?

Before we dive into React without JSX, let's first understand what JSX is. JSX, or JavaScript XML, is a syntax extension for JavaScript that looks similar to HTML. It's commonly used with React to describe what the UI should look like. However, JSX is not a requirement for using React. React can be used without JSX, which is what we'll explore in this tutorial.

ReactJS - React Without JSX

Why Use React Without JSX?

You might be wondering, "If JSX is so common, why would we want to use React without it?" Great question! There are a few reasons:

  1. Learning the core concepts: Understanding how React works without JSX can give you a deeper understanding of the library.
  2. Build tool limitations: Some build environments might not support JSX compilation.
  3. Personal preference: Some developers simply prefer writing pure JavaScript.

Creating Elements with React.createElement()

The heart of using React without JSX is the React.createElement() function. This function is what JSX compiles down to anyway, so we're just cutting out the middleman!

Let's start with a simple example:

const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);

In this example, we're creating an h1 element with a class of 'greeting' and the text content 'Hello, world!'. Let's break down the arguments:

  1. The first argument ('h1') specifies the type of element we want to create.
  2. The second argument ({className: 'greeting'}) is an object containing the props for the element.
  3. The third argument ('Hello, world!') is the content of the element.

If we were to write this in JSX, it would look like this:

const element = <h1 className="greeting">Hello, world!</h1>;

See how much more compact JSX is? But don't worry, with practice, creating elements without JSX becomes second nature!

Nesting Elements

Now, let's try something a bit more complex. How about creating a div with two child elements?

const element = React.createElement(
  'div',
  null,
  React.createElement('h1', null, 'Welcome'),
  React.createElement('p', null, 'This is a paragraph.')
);

This creates a structure equivalent to:

<div>
  <h1>Welcome</h1>
  <p>This is a paragraph.</p>
</div>

Notice how we nest createElement calls to create child elements. The null arguments are where we would put props if we needed them.

Creating Components

Components are the building blocks of React applications. Let's create a simple functional component without JSX:

function Welcome(props) {
  return React.createElement(
    'h1',
    null,
    'Welcome, ' + props.name
  );
}

To use this component, we would do:

const element = React.createElement(Welcome, {name: 'Alice'});

This is equivalent to the JSX:

const element = <Welcome name="Alice" />;

Handling Events

Event handling in React without JSX is very similar to with JSX. Let's create a button that logs a message when clicked:

function handleClick() {
  console.log('Button clicked!');
}

const button = React.createElement(
  'button',
  {onClick: handleClick},
  'Click me'
);

Here, we're passing the handleClick function as the onClick prop to the button element.

Conditional Rendering

Conditional rendering is a bit more verbose without JSX, but still entirely possible:

function Greeting(props) {
  if (props.isLoggedIn) {
    return React.createElement('h1', null, 'Welcome back!');
  } else {
    return React.createElement('h1', null, 'Please sign up.');
  }
}

const element = React.createElement(
  Greeting,
  {isLoggedIn: true}
);

Lists and Keys

Rendering lists without JSX requires us to use Array.map() explicitly:

const numbers = [1, 2, 3, 4, 5];

const listItems = numbers.map((number) =>
  React.createElement('li', {key: number.toString()}, number)
);

const list = React.createElement('ul', null, listItems);

Notice how we're still using the key prop, which is crucial for React's reconciliation process.

Methods Table

Here's a table summarizing the key methods we've discussed:

Method Description Example
React.createElement() Creates a React element React.createElement('div', null, 'Hello')
Array.map() Transforms array elements numbers.map(n => React.createElement('li', null, n))
React.render() Renders a React element to the DOM ReactDOM.render(element, document.getElementById('root'))

Conclusion

While JSX certainly makes writing React code more intuitive and readable, understanding how to use React without JSX gives you a deeper appreciation for what's happening under the hood. It's like learning to drive a manual car before an automatic - it gives you more control and understanding of the process.

Remember, whether you use JSX or not, the core principles of React remain the same. Components, props, state, and the virtual DOM all work in the same way. JSX is just syntactic sugar that makes the coding process a bit sweeter!

So, the next time you're debugging a React application and you see React.createElement() in the compiled code, you'll know exactly what's going on. Happy coding, and may your React elements always render true!

Credits: Image by storyset