React.js is a popular JavaScript library for building user interfaces, primarily for single-page applications where you need a fast and interactive user experience. One of the core concepts in React is the use of components and props. In this chapter, we will explore these concepts in depth, starting from the basics and gradually moving towards more advanced topics.
Components are the building blocks of any React application. They let you split the UI into independent, reusable pieces that can be managed separately. There are two main types of components in React:
Functional components are JavaScript functions that return React elements. They are the simplest way to create a component in React.
function Welcome(props) {
return Hello, {props.name}
;
}
Welcome
is a functional component.props
as an argument.<h1>
tag with a dynamic value {props.name}
.
// Usage
function Welcome(props) {
return Hello, {props.name}
;
}
// Output
Hello, Sara
Class components are more feature-rich than functional components. They extend from React.Component
and have access to lifecycle methods.
class Welcome extends React.Component {
render() {
return Hello, {this.props.name}
;
}
}
Welcome
is a class component.React.Component
.render
method returns a React element.this.props
.
// Usage
// Output
Hello, Sara
Props (short for properties) are read-only attributes used to pass data from a parent component to a child component.
Props are passed to components in the same way attributes are passed to HTML elements.
function Greeting(props) {
return Hello, {props.name}
;
}
function App() {
return ;
}
Greeting
component receives name
as a prop.App
component passes name="World"
to Greeting
.
// Output
Hello, World
You can define default values for props using the defaultProps
property.
function Greeting(props) {
return Hello, {props.name}
;
}
Greeting.defaultProps = {
name: 'Stranger'
};
function App() {
return ;
}
Greeting.defaultProps
sets name
to 'Stranger'
if no name
prop is provided.
// Output
Hello, Stranger
Prop types are a mechanism to ensure that components receive props of the correct type. React has a built-in type-checking mechanism called prop-types
.
import PropTypes from 'prop-types';
function Greeting(props) {
return Hello, {props.name}
;
}
Greeting.propTypes = {
name: PropTypes.string.isRequired
};
function App() {
return ;
}
PropTypes.string.isRequired
ensures name
is a string and required.You can add custom validation for props using functions.
function Greeting(props) {
return Hello, {props.name}
;
}
Greeting.propTypes = {
name: function(props, propName, componentName) {
if (!/^[A-Z]/.test(props[propName])) {
return new Error(
`Invalid prop \`${propName}\` supplied to` +
` \`${componentName}\`. Validation failed.`
);
}
}
};
function App() {
return ;
}
name
starts with an uppercase letter.
// Output
Error: Invalid prop `name` supplied to `Greeting`. Validation failed.
Components can be composed together to build more complex UIs.
function Avatar(props) {
return
;
}
function UserInfo(props) {
return (
{props.user.name}
);
}
function Comment(props) {
return (
{props.text}
{formatDate(props.date)}
);
}
Avatar
, UserInfo
, and Comment
are composed together.While props are used to pass data from parent to child, state is used to manage data within a component.
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = { date: new Date() };
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
tick() {
this.setState({
date: new Date()
});
}
render() {
return (
Hello, world!
It is {this.state.date.toLocaleTimeString()}.
);
}
}
Clock
is a class component with state.state
holds the current date.componentDidMount
sets up a timer.componentWillUnmount
clears the timer.tick
updates the state.render
displays the current time.A clock that updates every second.
function Display(props) {
return {props.message}
;
}
class Display extends React.Component {
constructor(props) {
super(props);
this.state = { message: 'Hello' };
}
updateMessage() {
this.setState({ message: 'Goodbye' });
}
render() {
return (
{this.state.message}
);
}
}
Display
manages state and can update it.updateMessage
changes the state and re-renders the component.Components: Independent, reusable pieces of UI.
Props: Read-only attributes used to pass data from parent to child components.
In this example, we will create a user profile card that displays user information passed through props.
import React from 'react';
function UserProfile(props) {
return (
{props.name}
{props.bio}
);
}
export default UserProfile;
Explanation:
UserProfile
component receives avatarUrl
, name
, and bio
as props.
import React from 'react';
import UserProfile from './UserProfile';
function App() {
const user = {
avatarUrl: 'https://example.com/avatar.jpg',
name: 'John Doe',
bio: 'Software engineer with a passion for open-source projects.'
};
return (
);
}
export default App;
// Output
John Doe
Software engineer with a passion for open-source projects.
In this example, we will create a simple Todo list application where you can add and remove tasks.
import React from 'react';
function TodoItem(props) {
return (
{props.task}
);
}
export default TodoItem;
TodoItem
component receives task
, index
, and removeTask
as props.
import React, { useState } from 'react';
import TodoItem from './TodoItem';
function TodoList() {
const [tasks, setTasks] = useState([]);
const [newTask, setNewTask] = useState('');
const addTask = () => {
if (newTask.trim()) {
setTasks([...tasks, newTask]);
setNewTask('');
}
};
const removeTask = (index) => {
setTasks(tasks.filter((task, i) => i !== index));
};
return (
Todo List
setNewTask(e.target.value)}
placeholder="Add a new task"
/>
{tasks.map((task, index) => (
))}
);
}
export default TodoList;
TodoList
component uses state to manage tasks and the new task input.addTask
function adds a new task to the list.removeTask
function removes a task by index.TodoItem
components.
import React from 'react';
import TodoList from './TodoList';
function App() {
return (
);
}
export default App;
// Output //
Todo List
-
Sample Task
In this example, we will create a modal component that can be opened and closed.
import React from 'react';
import './Modal.css'; // Assuming you have some basic CSS for the modal
function Modal(props) {
if (!props.isOpen) {
return null;
}
return (
×
{props.title}
{props.children}
);
}
export default Modal;
Modal
component receives isOpen
, onClose
, title
, and children
as props.isOpen
is true.
import React, { useState } from 'react';
import Modal from './Modal';
function App() {
const [isModalOpen, setIsModalOpen] = useState(false);
const openModal = () => {
setIsModalOpen(true);
};
const closeModal = () => {
setIsModalOpen(false);
};
return (
This is the content of the modal.
);
}
export default App;
// Output //
×
My Modal
This is the content of the modal.
Understanding components and props is fundamental to mastering React. Components are the building blocks of your UI, and props allow you to pass data between these components. By leveraging these concepts, you can build dynamic and reusable UI elements. As you progress, you'll encounter more advanced topics like state management and lifecycle methods, which further enhance your ability to create complex and efficient React applications.Happy coding !❤️