> For the complete documentation index, see [llms.txt](https://sydrawat.gitbook.io/react/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sydrawat.gitbook.io/react/introduction/components.md).

# Components

## Components

Components are the **core building block of React apps**. Actually, React really is just a library for creating components in its core.

A typical React app therefore could be depicted as a **component tree** - having one root component ("App") and then an potentially infinite amount of nested child components.

Each component needs to return/ render some **`JSX`** code - it defines which HTML code React should render to the real DOM in the end.

**`JSX` is NOT HTML** but it looks a lot like it. Differences can be seen when looking closely though (for example `className` in `JSX` vs class in "normal HTML"). `JSX` is just syntactic sugar for JavaScript, allowing you to write HTML-ish code instead of nested `React.createElement(...)` calls.

When creating components, you have the choice between two different ways:

1. **Functional Components**

```jsx
const Cmp = () => {
  return <div> Some JSX </div>;
}
```

1. **Class-based Components**

```jsx
class Cmp extends Component {
  render() {
    return <div> Some JSX </div>
  }
}
```

It's best practice to use *functional components* as much as possible.

### The create-react-app template structure

* **node\_modules**: contains all the project dependencies
* **public**: contains all the compiled and bundled project files
* **\[.gitignore, package.json, README.md, yarn.lock]**: listing out dependencies, project build, dev/env. Lock file for version control management. Ignore file is to exclude things from remote repo.
* **src**: contains all the styles and components

{% code title="App.js" %}

```jsx
import React, {Component} from "react"
import "./styles.css"

const App = () => {
  return (
    <div className="App">
      <h1>Hello React</h1>
      <h2>This is a react web page!</h2>
    </div>
  );
}

export default App;
```

{% endcode %}

{% code title="Index.js" %}

```jsx
import ReactDOM from "react-dom"
import App from "./app"

const rootElement = document.getElementById("root")
ReactDOM.render(<App />, rootElement);
```

{% endcode %}

In the `index.js` file, the `root` element is defined in the `index.html`, which is present in the public folder. The above `ReactDOM.render()` function call will bind the `<App />` component (defined in the `app.js` file) to the `rootElement`.

**NOTE:** The `render()` function call can have only 1 main `<div>` element, and we have to nest everything inside of this one main `<div>` element. This is somewhat loosened in *React v.16^*

But it is best to practice to have only 1 root element or component.

### Understanding `JSX`

Consider the example in `app.js` file:

{% code title="App.js" %}

```jsx
import React, {Component} from 'react'
import './style.css'

const App = () => {
  return (
    <div className="App">
      <h1>Hello React</h1>
      <h2>This is a React App</h2>
    </div>
  );
}

export default App;
```

{% endcode %}

If you notice the `<div>` component, the `className` is not the usual HTML syntax, it's JSX. So, at the back, this is not exactly how it is compiled.

The `<div className="App">` `JSX` code is converted to:

```jsx
return React.createElement(div, null, 'h1', 'Hello React');

// h1 Hello React
```

In the `React.createElement()` function, the parameter list is:

* **div:** This is the first parameter, which translates to which element (*or a React component)* should be rendered in the DOM.
* **null:** This is the second parameter, which is the config for the JS object.
* **h1, 'Hello React':** The parameters after the first two are referred to as `children`. These children components or elements are the ones to be nested inside the `div` in the first parameter (*which could also be a React component*). There can be infinite number of children.

But in the above example, the `h1` tag is not rendered as an HTML `h1` tag, it's rendered as plain text. So, as mentioned above, we have to nest this element inside the main `div` element, like so:

```jsx
return React.createElement(div, {className: 'App'}), React.createElement(h1, null, 'Hello React'));

// <h1>Hello React</h1>
```

So here, instead of `null` in the second parameter, we pass the `JSX` element property of `className` , and then nest the `h1` element within the `div`.

This is what `JSX` get compiled to by the build tools included in the create-react-app. Hence, this is why we need to import `React, {Component} from 'react'` even though we never use it in our `JSX` code.

### React Components

**Functional Components**

```jsx
import React, {Component} from 'react'
const Comp = () => {
  return(
    <div>Some JSX</div>
  );
}
```

**Class Components**

```jsx
import React, {Component} from 'react'
class Comp extends Component {
  render() {
    return(
      <div>Some JSX</div>
    )
  }
}
```

### Dynamic content in components

#### `props`

Attribute values that we pass to a component to render dynamic data.

Example:

```jsx
<Person name='Sid' age='25' />
<Person name='Max' age='26' />

// In the component
const Person = ({name, age}) => {
  return (
    <p> I am {name} and {age} years old</p>
  );
}
```

In the above example, I have used *object de-structuring* to make the code more "readable". If you're not familiar with object de-structuring, you can use the other syntax as well:

```jsx
const Person = (props) => {
  return(
    <p>I am {props.name} and {props.age} years old</p>
  );
}
```

This, obviously is tedious to write since we have to use `props.<propertyName>` every time we need to access the property of that component. So, it's always better to use object de-structuring whenever possible.

#### The `children` prop

If there is any data between the opening and closing tags of a React component, we call those data types as children props.

Example:

```jsx
<Person name="Sid" age="25">Hobbies: Art</Person>
```

In our React component:

```jsx
const Person = ({name, age, children}) => {
  return (
    <div>
      <p>I am {name} and {age} years old</p>
      <p>{children}</p>
    </div>
  );
}
export default Person
```

`'children'` is a reserved keyword in React, so if there are no child components within the parent component, i.e, between the opening and closing tags of the outer component, then `children` will be `null`.

#### `state`

The state of a component is managed from within the component.

**NOTE:** These are available only in class based components, which extend the `Component` class from `react`.

`State` is a reserved keyword and is of type `Object`.

Example:

```jsx
state = {
  persons: [
    {name: 'Sid', age:'26'}
    {name: 'Max', age:'27'}
    {name: 'Dennis', age:'28'}
  ]
}
```

To access the state properties on the components:

```jsx
<Person name={this.state.persons[0].name} age={this.state.persons[0].age} />
```

### Handling events with methods

Refer to [Event Handling page](https://app.gitbook.com/s/-MZvh-eMIQtgB00n2d-q/introduction/03%20-%20Event%20Handling%2076db7ecaeaa9441f916669dcd14966a9.md) on this notebook for more events that we can listen to.

Example:

```jsx
switchNameHandler = () => {
  console.log('clicked')
}

<button onClick={this.switchNameHandler}>Switch Name</button>
```

### Manipulating the state

#### **Class based components**

```jsx
state = {
  persons: [
    {name: 'Sid', age:'26'}
    {name: 'Max', age:'27'}
    {name: 'Dennis', age:'28'}
  ],
  otherState: 'some other state value'
}

switchNameHandler = () => {
  this.setState({
    persons: [
      {name: 'Sid', age:'27'}
      {name: 'Max', age:'27'}
      {name: 'Dennis', age:'29'}
    ]
  });
}
```

The `setState()` function is provided by React `Component`, which we import initially.

In the `setState()`, we only change a part of the original `state`, then the updates to the original `state` are merged from the `eventHandler`, w

#### **Functional Components**

`React Hooks` are the way in which we manipulate state in functional components in React.

There are many hooks, but we will use the `useState` hook to manipulate state in the functional components here.

**NOTE:** We can have as many `useState` hooks in our React functional component.

The `useState` hook returns an array with exactly 2 elements:

* 1st element is the **current state**
* 2nd element is a **function that allows us to update the state**

```jsx
import React, {useState} from 'react'
```

**NOTE:** We can use array de-structuring here to capture both the elements that the `useState` hook provides us with.

```jsx
const [personState, setPersonState] = useState({
  persons: [
    {name: 'Sid', age:'26'}
    {name: 'Max', age:'27'}
    {name: 'Dennis', age:'28'}
  ],
  otherState: 'some other state value'
})
```

Let's implement the `eventHandler`

```jsx
const switchNameHandler = () => {
  setPersonState({
    persons: [
      {name: 'Sid', age:'27'}
      {name: 'Max', age:'27'}
      {name: 'Dennis', age:'29'}
    ]
  });
}
```

In hooks, we do not use the `this` keyword to call the event handler

```jsx
<button onClick={switchNameHandler}>Switch Name</button>

//add props to Component

<Person name={personState.persons[0].name} age={personState.persons[0].age}/>
```

**NOTE:** When we are updating the state using the `useState()` hook, we need to manually update or add the other data as well, because this hook replaces the whole state, and does not merge the state like back in `this.setState()`

```javascript
console.log(personState) //before clicking 'Switch Name'
/*
    persons: [
    {name: 'Sid', age:'26'}
    {name: 'Max', age:'27'}
    {name: 'Dennis', age:'28'}
    ],
    otherState: 'some other state value'
*/
```

```javascript
console.log(personState) //after clicking 'Switch Name'
/*
    persons: [
    {name: 'Sid', age:'27'} --> age updated
    {name: 'Max', age:'27'}
    {name: 'Dennis', age:'29'} --> age updated
    ],
    ~~otherState: 'some other state value'~~ --> state property is lost
*/
```

To retain `otherState` within the state when using `useState` hook, we need to manually add the state property when manipulating the state:

```jsx
const switchNameHandler = () => {
  setPersonState({
    persons: [
      {name: 'Sid', age:'27'}
      {name: 'Max', age:'27'}
      {name: 'Dennis', age:'29'}
    ],
    otherState: 'some other state value'
  });
}
```

#### Passing method reference b/w components

We can also pass methods ( as a reference) as `props` to components!

```jsx
const switchNameHandler = () => {
  //perform state manipulation
}

<Person
  name={this.state.persons[0].name}
  age={this.state.persons[0].age}
  click={this.switchNameHandler}
/>
```

In the `Person` component:

```jsx
import React, {Component} from 'react'
const Person = ({name, age, click, children}) => {
  return (
    <p onClick={click}>
      Hi! I am {name} and {age} years old.
      {children}
    </p>
  );
}
```

In the above example, we passed a function or method reference to a `Person` component, which does not have direct access to the state, but still manipulates the state in the app.

#### Two way binding in components

Listen for text input and change the name of the person accordingly. Also show the initially set name in the text field.

{% code title="App.js" %}

```jsx
nameChangeHandler = (event) => {
    this.setState({
    persons: [
        {name: 'rahul', age:'28'},
        {name: event.target.value, age: 28},
        {name: 'dennis', age: 29}
    ]
    })
}

render() {
  return(
    <Person 
      name={this.state.persons[1].name}
      age={this.state.persons[1].age}
      change={this.nameChangeHandler}
    />
  );
}
```

{% endcode %}

{% code title="Person.js" %}

```jsx
const Person = ({name, age, change, children}) => {
  return (
    <div>
      <p>
        I am {name} and {age} years old
        {children}
      </p>
      <input type="text" onChange={change} value={name}/>
    </div>
  );
}
```

{% endcode %}

### Styling React Components

* **Using `stylesheets`**: This is same as using the basic HTML, CSS and JS web page, where we have all our stylesheets in a separate file, and then we inject these files into the component.

  **NOTE:** The styles via external files are global.

We `import` the stylesheet like so:

```jsx
import './style.css'
```

`Webpack` is a tool that helps it recognize and compile it *behind-the-scene.*

* **Inline styles**: For inline styles, we create a `style object` inside the component, inside the `render()` method call:

```jsx
render() {
  const style={
    backgroundColor: 'white',
    font: 'inherit',
    border: '1px solid black',
    padding: '8px',
    cursor: 'pointer'
  }
  return (
    <button style={style}> Click Me</button>
  );
}
```

**NOTE:** All the styles in inline styles are `camelCase`. Styles that are inline have a scope limited to that component itself!

## Stateless v/s Stateful Components

It does not mean if a component is a class-based component, it is a stateful component, and if a component is a functional component, it is a stateless component. But, this was the scenario before the introduction of React hooks in v16.

So, a stateful component is the one, which implements the `useState()` or `state` , and the one that doesn't, is a stateless component.

### Class based v/s Functional Components

#### **Class Based**

```jsx
class XY extends Component {...}
```

* Has access to state
* Uses Lifecycle Hooks

Access to `state` and `props` via `this` keyword.

```jsx
this.state.XY
this.state.props
```

**NOTE:** Unless you want to manage state or access to lifecycle hooks, do not use class based components!

#### **Functional Components**

```jsx
const XY = () => {...}
```

* Access to state using `useState()`
* No lifecycle hooks

Access to props via `props`

```jsx
props.XY
```

**NOTE:** This should be the preferred way to create components and state management, without the use of lifecycle hooks!


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://sydrawat.gitbook.io/react/introduction/components.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
