๐งฑComponents
Basic building blocks of a React app.
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:
Functional Components
Class-based Components
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
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
JSX
Consider the example in app.js
file:
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:
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 thediv
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:
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
Class Components
Dynamic content in components
props
props
Attribute values that we pass to a component to render dynamic data.
Example:
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:
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
children
propIf there is any data between the opening and closing tags of a React component, we call those data types as children props.
Example:
In our React component:
'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
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:
To access the state properties on the components:
Handling events with methods
Refer to Event Handling page on this notebook for more events that we can listen to.
Example:
Manipulating the state
Class based components
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
NOTE: We can use array de-structuring here to capture both the elements that the useState
hook provides us with.
Let's implement the eventHandler
In hooks, we do not use the this
keyword to call the event handler
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()
To retain otherState
within the state when using useState
hook, we need to manually add the state property when manipulating the state:
Passing method reference b/w components
We can also pass methods ( as a reference) as props
to components!
In the Person
component:
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.
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:
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 therender()
method call:
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
Has access to state
Uses Lifecycle Hooks
Access to state
and props
via this
keyword.
NOTE: Unless you want to manage state or access to lifecycle hooks, do not use class based components!
Functional Components
Access to state using
useState()
No lifecycle hooks
Access to props via props
NOTE: This should be the preferred way to create components and state management, without the use of lifecycle hooks!
Last updated