React Js has become an essential tool in modern web development due to its efficient and scalable approach to building user interfaces. In this article, I will dive into the core concepts of React Js, including components, JSX, props, lifecycle methods, and event handling.
1. Components
Components are the fundamental building blocks of a React application. They are reusable, self-contained pieces of code for rendering a specific UI part. React components can be either class-based or function-based. Function-based components are becoming more prevalent due to the introduction of React Hooks.
Below is an example of a simple function component. The component represents an html input with a label. Then I can use that component in forms where I expect user input.
const Input = (props) => {
return
<>
<label for={props.inputId}>{props.label}:</label>
<input id={props.inputId} name={props.inputName} type="text" />
</>
}
Note that the fragment <>...</>
wraps the function return. In React, when I return JSX from a component, I must wrap it at least in a single parent element because a component can only return one top-level element.
This limitation exists because a component's render method should produce a consistent and predictable structure, making it easier to manage and understand the component hierarchy. This rule applies when my return consists of multiple elements.
To use this Input component in another component, you would import it and include it like so:
import Input from './path/to/Input';
const RegistrationForm = () => {
return (
<form>
<Input inputId="name" inputName="name" label="First Name" />
<Input inputId="address" inputName="address" label="Address" />
</form>
)
}
There are several restrictions to follow when creating a React Js component. At this point, It is important to note the following. I will explain more later in the article.
- Naming convention: Component names must start with a capital letter. That distinguishes them from regular HTML tags and built-in React components (e.g., div, span, React.Fragment).
- Single root element: A component must return a single top-level element or React fragment. That ensures a consistent and predictable structure in the component hierarchy.
2. JSX (JavaScript XML)
JSX is a syntax extension for JavaScript that allows us to write HTML-like code within your JavaScript code. JSX makes writing and understanding component structure easier, and it is transformed into JavaScript during the build process. In my above example, I returned a JSX element.
<>
<label for={props.inputId}>{props.label}:</label>
<input id={props.inputId} name={props.inputName} type="text" />
</>
When returning a JSX element in React, there are some restrictions and guidelines to follow. I will explain most of them when I explain the code examples.
- Single root element: A JSX expression must have a single root element. You cannot return adjacent JSX elements without wrapping them in a single parent element or a React fragment.
If you need to return multiple elements without adding an extra node to the DOM, you can use a React fragment,
either with the short syntax<>...</>
or the longer syntax<React.Fragment>...</React.Fragment>
. - Closing tags: All JSX elements must be closed. Self-closing tags should include a forward slash before the closing angle bracket
(e.g.,<img src="image.jpg" alt="example" />
). - Attribute names: Some HTML attribute names are reserved words in JavaScript, so they must be replaced with their JSX equivalents when using them as props.
For example, theclass
becomesclassName
, andfor
becomeshtmlFor
. - Expressions: If I need to include JavaScript expressions within your JSX, I must enclose them in curly braces
({})
.
Plain text and expressions can be mixed inside a JSX element. - Style prop: Inline styles in JSX are specified as objects. The style prop takes an object with camelCased property names
(e.g.,<div style={{ color: 'red', fontSize: '16px' }}>Hello!</div>
). - Comments: To include comments inside JSX, I need to use the JavaScript block comment syntax enclosed in curly braces,
like this:{/* This is a comment inside JSX */}
. - Keys for lists: When rendering a list of elements in React, I should provide a unique "key" prop for each element. More on this later.
3. Props
In React, data is passed from parent components to child components through "props" (short for properties). Props are read-only, meaning a component should never modify its props.
Here's an example of using props:
const Input = (props) => {
return
<>
<label for={props.inputId}>{props.label}:</label>
<input id={props.inputId} name={props.inputName} type="text" />
</>
}
const RegistrationForm = () => {
return (
<form>
<Input inputId="name" inputName="name" label="First Name" />
<Input inputId="address" inputName="address" label="Address" />
</form>
)
}
In the above example, I re-use the Input
component in my Registration
component to input the name and address. In each usage, I pass in the props to the Input component.
The Input
component uses those props to display the input with the desired label, name, id, etc.
4. Lifecycle Methods
Lifecycle methods are special methods in React components. They allow us to execute code at specific points during the component's lifecycle. The component lifecycle includes mounting, updating, and unmounting.
With the introduction of React Hooks, lifecycle methods can be replicated in function components using the useEffect
hook.
Here's an example of using lifecycle methods
const RegistrationForm = () => {
useEffect(() => {
console.log('Executes everytime the component updated')
})
return (
<form>
<Input inputId="name" inputName="name" label="First Name" />
<Input inputId="address" inputName="address" label="Address" />
</form>
)
}
I will explain the lifecycle hooks in great detail in the upcoming article.
5. Event Handling
In React, event handling uses event listeners attached to DOM elements. Event listeners are usually defined as functions in function components.
Here's an example of event handling:
const Input = (props) => {
const handleClick = () => {
alert('Input changed')
}
return
<>
<label for={props.inputId}>{props.label}:</label>
<input id={props.inputId} name={props.inputName} type="text" onClick={handleClick}/>
</>
}