Skip to main content

React

Welcome to your React guide on Dynatrace Developer. If you've reached this page, you likely wish to get started with React.

The following documentation will introduce you to important React concepts. By the end of this guide, you'll have enough knowledge to start building React app. Although this guide won't cover everything about React, we've provided helpful links to resources for further reading.

Prerequisite

React is a JavaScript library. You'll need a good understanding of JavaScript and HTML concepts to make the most of this guide. If you need a refresher, look at this JavaScript tutorial.

What's React?

A JavaScript library for building user interfaces -- From React docs

It's a library that helps you create user interfaces (UIs) using composable UI elements.

Following are some key features of React:

  • Component-based: React components are the building blocks of a React app. Think of components as something similar to HTML elements. In React, you create encapsulated components with their state, and then you can combine them to make an application.

  • Declarative: You can create your views declaratively in React. It makes code easier to understand.

Create components

Creating a component is as easy as creating a JavaScript function that returns some markup. Take a look at the following example:

function MyComponent() {
return <span>My Fancy Component</span>;
}

You have a function named MyComponent that returns the span element.

Render components

To render your components, you create a React root using createRoot by passing the DOM container. This React root is then used to render React elements into the DOM with the render function, as shown:

import { createRoot } from 'react-dom/client';

function MyComponent() {
return <span>My Fancy Component</span>;
}

const domRoot = document.getElementById('root');
const reactRoot = createRoot(domRoot);

reactRoot.render(<MyComponent />);

Write markup

You've already seen that react components return markup. This markup isn't HTML. It's called JSX, syntactic sugar for JavaScript, to write XML-like declarative code.

Since JSX is just syntactic sugar, it's also optional. The compiler under the hood converts JSX into JavaScript function calls. Following is an example of MyComponent with and without JSX:

// jsx
function MyComponent() {
return <span>My Fancy Component</span>;
}

// without jsx
function MyComponent() {
return React.createElement('span', null, 'My Fancy Component');
}

The compiler replaces JSX with React.createElement function calls in this example. Therefore, you can also assign JSX to a variable, pass it to a function, and return it from a function like a normal JavaScript function. Following are some examples of valid JSX code along with React.createElement version:

// assign jsx to variable
const MyElement = <h1>Hi there!</h1>;
// return jsx from a function
const doSomething = () => {
return <span>Do Something</span>;
};
// jsx as a function argument
const anotherFunction = (jsxValue) => {
// do something with jsxValue here
};

anotherFunction(<h1>Hello</h1>);
Note

React 17 introduced a new JSX transform. With this update, JSX isn't coupled with React imports. Under the hood, compilers can transform your JSX using this new transform.

For example, instead of React.createElement, the compiler can use jsx method from react/jsx-runtime. Look at the MyComponent using this new transform:

// Inserted by a compiler (don't import it yourself!)
import { jsx as _jsx } from 'react/jsx-runtime';

function MyComponent() {
return _jsx('span', { children: 'My Fancy Component' });
}

As an app developer, nothing changes for you.

To learn more, visit Introducing the new JSX transform.

Add expressions in JSX

You can also add JavaScript expressions in your JSX code using curly braces. In the following example, you're doing the following:

  • create a variable fullName
  • then wrap it around curly braces in the JSX and assign that to the greeting variable
  • finally, use the greeting variable in the return expression

Take a look at the following code snippet:

function ExpressionComponent() {
const fullName = 'Lorem Stark';
const greeting = <h1>Welcome {fullName}</h1>;

return (
<div>
{greeting}
</div>
);
}

It will render <h1>Welcome Lorem Stark</h1> on the page.

Conditional rendering

You can also conditionally render some JSX. In the following example, the app only renders <span>Dark Mode</span> when darkMode is true:

function ConditionalRender() {
let darkMode = true; // boolean value
return (
<div>{darkMode && <span>Dark Mode</span>}</div>;
);
}

You can also use a ternary operator to have if/else like rendering. In the following example, if darkMode is true the app renders <span>Dark Mode</span>, else it renders <span>Light Mode</span>.

function TernaryComponent() {
let darkMode; // boolean value
return <div>{darkMode ? <span>Dark Mode</span> : <span>Light Mode</span>}</div>;
}

Render list

You can also render objects and arrays. In the following example, the app renders the list of people on the page by returning JSX from Array's map:

function AComponentWithMap() {
const people = [
{
name: 'Philip Prosacco',
id: 'abc',
},
{
name: 'Allison Nolan',
id: 'xyz',
},
];

return (
<div>
<h2>List of people</h2>
<ul>
{people.map((person) => (
<li key={person.id}>{person.name} </li>
))}
</ul>
</div>
);
}
Tip

React uses the key prop to identify each element in an array uniquely. To learn more, read List and Keys.

Things to remember

Here are some things to remember:

  • You can mix HTML tags and React components in JSX.
  • A React component can only return one root JSX tag. If you have to return many elements from a React component, you can wrap a div or React.Fragment component around them. Take a look at Fragment documentation.
  • You have to close all HTML tags and React components like <img/>.
Note

To learn more about JSX, visit Writing Markup with JSX

Props

In React, a component can receive input from its outer component. You can achieve this using props. Think of props as something similar to attributes in HTML.

In the following example, you have a StockDetail component that takes an object as an argument with two props, stockSymbol and stockValue, and shows them on page.

function StockDetail({ stockSymbol, stockValue }) {
return (
<div>
<h2>Stock Symbol: {stockSymbol}</h2>
<h3>Stock Value: {stockValue}</h3>
</div>
);
}

You can then pass the actual value of these props as follows:

<StockDetail stockSymbol={'SYM'} stockValue={24.4} />
Tip

It's how you can pass the data from parent to child component.

Event handling

The event handling in React is very similar to DOM. You write React events in camelCase and pass the function's name to it. In the following example, the app adds an onClick event listener to the button and attaches it to the handleOnClick function:

<button onClick={handleOnClick}>Click me!</button>

The event handler receives the event as an argument. You can also use the event to prevent the default behavior using preventDefault in your handler as shown:

function MyButton() {
function handleOnClick(e) {
e.preventDefault();
console.log('You clicked me!');
}
return <button onClick={handleOnClick}>Click me!</button>;
}
Note

To learn more, go to Responding to Events

Custom events

Like DOM events, you can also create custom events for your component. Custom events allow you to pass data from a child to a parent component.

In the following example, you create a MySpecialButton component with customEvent as a prop. Through this prop, you send custom events to the parent component. The parent component can attach the event handler to this event.

The MySpecialButton component returns a button. The app fires the customEvent when a user clicks the button. In this example, the app sends dataToParent as an event, but you can pass anything.

function MySpecialButton({ customEvent }) {
function handleOnClick(e) {
customEvent('dataToParent');
console.log('You clicked me!');
}

return <button onClick={handleOnClick}>I'm special!</button>;
}

As mentioned earlier, then you can attach the event handler to the customEvent like so:

<MySpecialButton customEvent={handleCustomEvent} />

Hooks

A hook is a special function that gives you access to the state and other React features in a React component.

By convention, the hook's name starts with use. React provides built-in hooks like useState, useEffect, and more. You can also create custom hooks to share stateful logic between many components.

The State hook

To create a local state in a React component, use the useState hook from React. Take a look at the following code:

const [state, setState] = useState(initialState);

The useState function returns an array with two items:

  • The first item is the current value of the state, initially set to the initialState provided.
  • The second item is a function that lets you update the state.

Example

In the following example, you have a MyDiceApp component. When a user clicks on the button, it generates a random dice count between one to six and stores it in the diceValue state using the setDiceValue function, as follows:

import { useState } from 'react';

function MyDiceApp() {
const [diceValue, setDiceValue] = useState();

function handleClick() {
const diceCount = Math.floor(Math.random() * 6 + 1);
setDiceValue(diceCount);
}

return (
<div>
<h2>Dice App</h2>
<button onClick={handleClick}>Roll Dice</button>
<h4>Dice Value: {diceValue}</h4>
</div>
);
}
Deep-dive

Setting the state doesn't change any value in the currently executing code. Take a look at the following code:

// imports
const [state, setState] = useState(0);

function handleAnEvent() {
setState(1);
console.log(state); // logs 0
}
// …

The log will still print 0 instead of 1. The new state is only available from the next render.

The Effect hook

The Effect hook allows you to perform side effects to changes in your react app. Take a look at the following code:

useEffect(callbackFn, dependencyArray);

The useEffect function takes two parameters:

  • The first parameter is an anonymous callback function that performs the side-effect.
  • The second item is an array of dependencies that tells react when to call the callback function.

Example

Add a useEffect hook to the earlier MyDiceApp component in the following example. This useEffect runs a side-effect each time the app updates the diceValue state and logs its value.

import { useState, useEffect } from 'react';

function MyDiceApp() {
const [diceValue, setDiceValue] = useState();

useEffect(() => {
console.log(diceValue);
}, [diceValue]);

function handleClick() {
const diceCount = Math.floor(Math.random() * 6 + 1);
setDiceValue(diceCount);
}

return (
<div>
<h2>Dice App</h2>
<button onClick={handleClick}>Roll Dice</button>
<h4>Dice Value: {diceValue}</h4>
</div>
);
}
Common Mistake

Very often, developers omit the dependency array in the useEffect hook, as follows:

useEffect(() => {
// do something
});

It will cause the callback function to be called with every re-render, potentially leading to infinite re-renders.

Rules of Hooks

  • Use your Hooks at the top of your React component, and don't call them inside loops, conditions, or nested functions. To know why, look at this Explanation.
  • Use Hooks only in your React function components or your custom hooks. React hooks won't work in a regular JavaScript function.
Note

To learn more about hooks, go to Built-in React Hooks

What's next?

Now you have a basic understanding of React, and it's time to put it into practice and build a Dynatrace App. Take a look at the following:

Further resources to learn React

Still have questions?
Find answers in the Dynatrace Community