This content originally appeared on DEV Community and was authored by Hiep Le
I'm Hiep. I work as a full-time software engineer. Most of my open-source projects are focused on one thing - to help people learn ?.
Before moving on with this part, you should follow the first part in this series:
The first part - Learn React By Building Netflix:
The repository helps you learn higher order components by building Netflix. It means that you are learning higher order components by building a real-life project. I will explain concepts in detail. This post is the fifth part in my series and it is suitable for beginners.
If you feel the repository is useful, please help me share the post and give me a ⭐. It will make me feel motivation to work even harder. I will try to make many open sources and share to the community.
I also created some series that help you improve your practical skills:
1. Master Design Patterns by Building Real Projects - Javascript.
Github: https://github.com/hieptl/master-javascript-design-patterns-by-building-real-projects
Preface
This course will help you to learn higher order components by building Netflix. It means that you are learning by doing a real-life project.
Table of Contents
No. | Topics |
---|---|
0 | How to Run the Project. |
1 | Live Demo. |
2 | Introduction about the Creator. |
2.1 | Greenwich University. |
2.2 | Hitachi Vantara Vietnam. |
3 | Prequisites. |
3.1 | Softwares. |
3.2 | Technical Skills. |
3.3 | Materials. |
4 | Purposes of the Course. |
4.1 | Final Project. |
4.2 | Job. |
5 | Higher Order Components. |
5.1 | Higher Order Functions. |
5.2 | What. |
5.3 | Why. |
5.4 | When. |
5.5 | How. |
6 | Scenarios |
7 | Summary. |
8 | Useful Resources to Learn React. |
9 | References. |
Table of Images.
No. | Topics |
---|---|
1 | Figure 1: Login Page - Netflix. |
2 | Figure 2: The Final Result. |
0. How to Run the Project.
Step 1: Clone the project by using git clone or download the zip file.
Step 2: Open "terminal" / "cmd" / "gitbash" and change directory to "netflix-clone" and run "npm install" to install dependencies.
Step 3: Run "npm start" to run the fron-end project.
1. Live Demo.
- https://1g1qt.csb.app/login
- Username: demo@gmail.com
- Password: 123456
2. Introduction about the Creator.
2.1. Greenwich University.
GPA 4.0 / 4.0.
Machine Learning paper - Recommendation System - IEEE/ICACT2020.
Co-Founder / Mentor IT club.
2.2. Hitachi Vantara Vietnam.
Employee of the year.
Second prize - innovation contest.
Techlead - HN branch.
One of CoE Leaders (Center of Excellence).
3. Prequisites.
3.1. Softwares.
Install NodeJS.
An IDE or a text editor (VSCode, Intellij, Webstorm, etc).
3.2. Technical Skills.
Basic programming skill.
Basic HTML, CSS, JS skills.
3.3. Materials.
Html, css, js (source code) was prepared because I want to focus on React and share knowledge about React. Building html and css from scratch would take a lot of time.
README.md (the md file will contain everything about the course).
Netflix data will be used to import to Firebase. In this course, we use Firebase as our back-end service.
4. Purposes of the Course.
4.1. Final Project.
The course would help you have understanding about React.
You could build the final project with end-to-end solution (front-end solution using React and back-end solution using Firebase).
4.2. Job.
- After finishing the course, you could get a job with fresher / junior position.
5. Higher Order Components.
5.1. Higher Order Functions.
- Higher-order function is a function that accepts another function as an argument or returns a function as a return value or both.
const firstOrderFunc = () => console.log ('Hello, I am a First order function');
const higherOrder = ReturnFirstOrderFunc => ReturnFirstOrderFunc();
higherOrder(firstOrderFunc);
5.2. What
- Higher-order component is a function that take a component as input and return a new component.
- It is called a pure function because it will not modify or copy any behaviour from its input component.
5.3. Why
There are some advangtages of higher-order components:
- Code reuse, logic and boostrap abstraction.
- Render hijacking.
- State abstraction and manipualtion.
- Props manipulation.
5.4. When
- In the case, we want to reuse code between component. We should use higher-order components.
Example: We often use modal UI in our applications. The modal UI is the same among the screens. The logic of turning on / off the modal may be dupplicated in different places. For this reason, we should find a good solution which helps us reuse the same logic. Higher-order components could be a good solution to hanlde that case.
5.5. How
Step 1: Create a function that accept another function as parameter.
Step 2: Add custom behaviour (state, styling, logic and so on).
Step 3: Return a new component.
6. Scenarios.
Figure 1. Login Page - Netflix.
We built the login page in the first parr of this series. However, we do not validate input email and password. Our scenarios will be like this:
Case 1: If user input invalid email or password, a modal will be displayed in order to show the error message.
Case 2: If user input input valid email and password. We will show the information if signed in user on the console.
As mentioned above, we need to diplay the error message by using a modal. Actually, we have several ways to achive the result. However, the optimal solution should be found and that solution should help us to reuse the logic of turning on / off the modal because we need to use the modal in different places such as "sign-up" feature, ...
We will build the idea by applying higher-order components.
Step 1: Install validator library to validate the input values by running npm install validator or yarn add validator.
Step 2: Write a function to validate the input values.
...
// import validator.
import validator from "validator";
...
...
const isUserCredentialsValid = () => {
return validator.isEmail(email) && validator.isLength(password, { min: 6 });
};
...
1st NOTE:
We are using validator libary in order to help us validate some common information such as email format, length of the values and so on. For this reason, we do not need to write everything from scratch.
In this case, we want to validate the email format and the minimum length of the password should by 6 characters.
- Step 2: Update the login function:
/**
* handle event when the user clicks on "Login" button.
*/
const login = () => {
if (isUserCredentialsValid()) {
// call firebase authentication service.
firebaseAuth
.signInWithEmailAndPassword(email, password)
.then((userCredential) => {
// Signed in
const user = userCredential.user;
// ...
console.log(`signed in user`);
console.log(user);
})
.catch((error) => {
console.log(error);
});
} else {
// call function to show the modal.
}
};
2nd NOTE:
We use isUserCredentialsValid() inside the login function. We want to ensure that the input values are valid before submitting to Firebase.
If the input values are not valid, we will show the modal to display the error message. We will comeback to it later.
Step 3: Create modal folder inside components folder. The folder is used to contain Modal component.
Step 4: Create Modal.js file inside modal folder.
const withModal = (WrapperComponent) => {
const showModal = ({ message }) => {
window.alert(message);
};
return function () {
return <WrapperComponent showModal={showModal} />;
};
};
export default withModal;
3rd NOTE
We define withModal as a higher-order component because it accept WrapperComponent as parameter and then return a new component.
As mentioned above, we use higher-order components to reuse logic and share the code between components. In this case, we reuse the logic of turning on / off the modal. In fact, the modal could be understood as a common component because, it is used frequently in different places.
We define showModal function that accept an object with the message property as parameter. We are use the default alert of window object instead of creating the new one because we want to focus on learning about higher-order components, you can custom you own modal.
The most important part is about
<WrapperComponent showModal={showModal} />
- We accept WrapperComponent as input and after adding custom behaviour, we return a new component and pass showModal function as props. The returned component is called EnhancedComponent.
- Step 5: Replace the LoginForm.js with the following code:
// import react.
import { useState } from "react";
// import firebase authentication.
import { firebaseAuth } from "../../firebase/firebase";
// import higher order components.
import withModal from "../modal/Modal";
// import validator.
import validator from "validator";
/**
* create LoginForm component.
*/
function LoginForm(props) {
// create email and password state to store user's credentials.
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const { showModal } = props;
const isUserCredentialsValid = () => {
return validator.isEmail(email) && validator.isLength(password, { min: 6 });
};
/**
* handle event when the user clicks on "Login" button.
*/
const login = () => {
if (isUserCredentialsValid()) {
// call firebase authentication service.
firebaseAuth
.signInWithEmailAndPassword(email, password)
.then((userCredential) => {
// Signed in
const user = userCredential.user;
// ...
console.log(`signed in user`);
console.log(user);
})
.catch((error) => {
console.log(error);
});
} else {
showModal({ message: "Your email and password are not correct" });
}
};
/**
* update email state when the user inputs the email field.
* @param {*} e - synthetic event to get the latest email's value.
*/
const onEmailChanged = (e) => {
// get email value.
const updatedEmail = e.target.value;
// update email state.
setEmail(() => updatedEmail);
};
/**
* update password state when the user input the password field.
* @param {*} e - synthetic event to get the latest password's value.
*/
const onPasswordChanged = (e) => {
// get password value.
const updatedPassword = e.target.value;
// update password state.
setPassword(() => updatedPassword);
};
return (
<div className="login-body">
<div className="login-body__form">
<h1>Sign In</h1>
<div className="login-body__input mb-16">
<input
type="text"
placeholder="Email or phone number"
onChange={onEmailChanged}
/>
</div>
<div className="login-body__input">
<input
type="password"
placeholder="Password"
onChange={onPasswordChanged}
/>
</div>
<button className="login-body__submit-btn" onClick={login}>
Sign In
</button>
<div className="login-body__options">
<span>Remember me</span>
<span className="login-body__need-help">Need help?</span>
</div>
<div className="login-body__footer">
<div className="login-body__fb">
<img
src="https://assets.nflxext.com/ffe/siteui/login/images/FB-f-Logo__blue_57.png"
alt="fb"
/>
<span>Login with Facebook</span>
</div>
<div className="login-body__new-to-nl">
<span>New to Netflix ?</span>
<span className="login-body__sign-up">Sign up now.</span>
</div>
<div className="login-body__google_captcha">
This page is protected by Google reCAPTCHA to ensure you're not a
bot.
<span className="login-body__learn-more">Learn more.</span>
</div>
</div>
</div>
</div>
);
}
// export LoginForm component.
export default withModal(LoginForm);
4th NOTE:
- We import the higher-order component.
// import higher order components. import withModal from "../modal/Modal"
- We use withModal as wrapper around LoginForm component.
// export LoginForm component. export default withModal(LoginForm);
- We show the modal if the input values are not value.
showModal({ message: "Your email and password are not correct" });
We pass LoginForm as WrapperComponent and return a new component with showModal function. Therefore, we can reuse the showModal function in different places by wrapping any components inside withModal component.
The final result will be like this:
Figure 1. The Final Result.
Summary
Higher-order component is a function that takes a component and returns a new component.
It is a pure function because it will not modify or copy any behaviour from its input component.
Higher-order components have many advantages such as code reuse, logic and bootstrap abstraction, state abstraction and manipulation, props manipulation and so on.
Thank you so much for taking the course. I hope that you could understand about Higher Order Components and you can build many real-life projects by using React (as front-end) and Firebase (as back-end) in order to solve many problems and make our life become better.
Useful Resources to Learn React.
[1]. https://reactjs.org/docs/getting-started.html.
References
[1]. https://reactjs.org/docs/getting-started.html.
[2]. https://firebase.google.com/docs/database.
[3]. https://firebase.google.com/docs/auth/web/password-auth.
[4]. https://firebase.google.com/docs/hosting.
This content originally appeared on DEV Community and was authored by Hiep Le
Hiep Le | Sciencx (2021-06-12T13:55:00+00:00) Learn React and Higher-Order Components By Building Netflix. Retrieved from https://www.scien.cx/2021/06/12/learn-react-and-higher-order-components-by-building-netflix/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.