Understanding React basics
To get started, open a project in your IDE so that we can explore a simple example. This is what a React app returning a simple Hello World
message looks like:
function App() { return ( <div> <p>Hello World!</p> </div> ) }
The first thing that comes to mind when seeing these code lines is probably that this looks just like XML/HTML! Indeed, it does, but these tags get converted into JavaScript by a preprocessor, so it’s JavaScript code that looks like XML/HTML tags. Hence the name JSX, which is short for JavaScript XML.
The JSX tags can be used much like XML/HTML tags; you can structure your code using the different types of tags, and you can style them using CSS files and the className
attribute, which is the React equivalent of HTML’s class
attribute.
On the other hand, you can insert JavaScript code anywhere in the JSX, either as a value for an attribute or inside a tag. You just have to put curly brackets around it. Please have a look at the following code, which uses a JavaScript variable inside JSX:
function App() { const userName = 'Some Name'; return ( <div> <p>Hello {userName}!</p> </div> ) }
In this example, we are greeting a user whose name we have previously stored in a userName
variable by inserting this userName
variable into our example code’s JSX.
These JSX tags are really handy, but what if I have some part of the code that I want to reuse throughout the code, such as a special kind of button or a sidebar element? This is where the component-based catchphrase from the ReactJS home page comes into play.
Understanding React components
Our example includes one component called App
. In this case, it’s a functional component. It’s also possible to use class components in React but most of the following examples will use the more common functional components. React allows you to write custom components and use them exactly like a normal JSX tag in another part of the code.
Let’s say we want to have a button that opens an external link to the ReactJS home page upon being clicked. We could define a custom ReactButton
component like this:
function ReactButton() { const link = 'https://reactjs.org'; return ( <div> <a href={link} target="_blank" rel="noopener noreferrer"> Go To React </a> </div> ) }
Then, we can use the button in the main component, using the empty tag notation as it doesn’t have any child components:
function App() { const userName = 'Some Name'; return ( <div> <p>Hello {userName}!</p> <ReactButton/> </div> ) }
As you can see, every component in React has to implement the return
function to render a view in the app. The JSX code can only be executed when it is called by the return
function, and there has to be one JSX tag that wraps all the other tags and components. There is no need to explicitly implement how the view should behave when the content changes – React automatically handles this. This is what we mean when we describe React as being declarative.
So far, we have seen why React is defined as a declarative, component-based JavaScript library for building user interfaces. But we haven’t talked about one of the main advantages of React yet: how it efficiently rerenders views. To understand this, we need to have a look at props and state.
Understanding React props and state
A prop is a parameter that is transferred from a parent component to a child component. Let’s say we want to create a WelcomeMessage
component that shows a welcoming text, including the username from the App
component.
This component could look like this:
function WelcomeMessage(props) { return ( <div> <p>Welcome {props.userName}!</p> <p>It's nice to see you here!</p> </div> ) }
Then, we can include it in the App
component:
function App() { const userName = "Some Name"; return ( <div> <WelcomeMessage userName={userName}/> <ReactButton/> </div> ) }
The name of the prop is used like an attribute on the JSX tag of the child component. By using props
as a parameter for the child component, all those attributes are automatically accessible in the child component, such as username
in our example.
What makes React so efficient is the fact that any time the value of a prop changes, only those components that are affected by that change are rerendered. This massively reduces the rerendering costs, especially for large applications with many layers.
The same goes for state changes. React provides the possibility to turn any component into a stateful component by implementing the state
variable in class components or the useState
Hook (more on Hooks in Chapter 3, Hello React Native) in functional components. The classical example of a stateful component is a Counter
:
function Counter () { const [numClicks, setNumClicks] = useState(0); return ( <div> <p>You have clicked {numClicks} times!</> <button onClick={() => setNumClicks(numClicks+1)> Click Me </button> </div> ) }
The numClicks
state variable is initialized with a value of 0
. Any time the user clicks on the button and the internal state of the Counter
component changes, only the content of the <p>
tag is rerendered.
ReactDOM is responsible for comparing all the elements in the UI tree with the previous ones and updating only the nodes whose content has changed. This package also makes it possible to easily integrate React code into existing web apps, regardless of what language they are written in.
When Facebook decided to become a mobile-first company in 2012, this learn once, write anywhere approach of React was applied to the development of mobile applications, which led to the emergence of React Native in 2013, where it is possible to write apps for iOS or Android using only JavaScript or TypeScript.
Now that we have learned what React is and how it works in general, let’s learn more about React Native.