Open up your terminal.
Make sure node and npm are working. Run the following commands:
node --versionIt should display version 14.x (or 16.x).
npx --versionAny version means it is installed.
If these are not installed install the latest version of node.
In your terminal, make a directory for your projects, and change directory to it. I like to keep my files in a directory named ctp under my home directory.
cd ~
mkdir ctp
cd ctpyou only have to
mkdir ctpif this directory doesn't already exist
Now we're going to create our first react app:
npx create-react-app learn-react-1
cd learn-react-1
npm startIf your browser opened up automatically and you see the spinning logo, then everything is working.
Open up the learn-react-1 directory in your text editor.
Let's take a look at /public/index.html specifically the <div id="root"></div>
Now let's go to the /src/index.js and let's delete all of the code in this file. This is the entry point to our React app. No need to worry about the rest of the files in src for now. We will eventually delete them all, and create new files ourselves.
When you delete all of the code and save the file, what happened in the browser?
In /src/index.js add the following code:
import React from 'react'
import ReactDOM from 'react-dom'
ReactDOM.render(
<h1>Hello World!</h1>,
document.getElementById("root")
);Let's break this code down.
- import statements
- ReactDOM.render(reactElement, htmlDOMContainer)
- JSX
This is not HTML, it is JSX.
Try to change the HTML, add some other tags. Try the following examples and observe the results.
<H1>Hello World!</H1><div>
<h1>Hello World!</h1>
<h1>Hi Again</h1>
</div><div>
<h1>Hello World!
<h1>Hi Again</h1>
</div><h1>Hello World!</h1>
<h1>Hi Again</h1>- all standard HTML tags are available in lowercase version
- all tags must be closed
- all JSX must have a single parent tag
The point of a component based system is to create reusable componenets. Let's make the following changes to our code:
import React from 'react'
import ReactDOM from 'react-dom'
function Welcome() {
return (
<div>
<h1>Welcome CTP Class</h1>
<p>My first component</p>
</div>
);
}
ReactDOM.render(
<Welcome />,
document.getElementById("root")
);What did we just do?
- components must begin with capital letters
- notice the
( )in the return - Try
- is a standard HTML tag?
We can and should create many small components, that we put together. Let's make the following changes:
...
function Student() {
return <div>- Sally is in class</div>;
}
function Welcome() {
return (
<div>
<h1>Welcome CTP Class</h1>
<p>Who is in class?</p>
<Student />
</div>
);
}
...- Try adding multiple
Studenttags in the Welcome component. What happens?
A component like Student is a lot more useful if we can dynamically change its content. We will do that now:
...
function Student(props) {
return <div>- { props.name } is in class</div>;
}
function Welcome() {
return (
<div>
<h1>Welcome CTP Class</h1>
<p>Who is in class?</p>
<Student name="Sally" />
<Student />
<Student />
</div>
);
}
...- add different names to the last two
Studenttags { }allows us to embed javascript within JSXpropsare always passed to componentspropsare immutable, what does that mean?- try changing
props.name = "Jose", what happens?
JSX is not HTML, but it does allow you to set standard HTML attributes with slightly different names.
Instead of class we use className. React's designers did this on purpose to differnetiate JSX from HTML.
There are many ways to handle CSS in React. For now we will keep it simple and use the file /src/index.css
in /src/index.css add the following to the bottom of the file:
.red-text {
color: red;
}in /src/index.js add the following below your import statements:
import './index.css'and make the following change:
...
function Student(props) {
return <div className="red-text">- { props.name } is in class</div>;
}
...Functional components are really great and powerful, but sometimes we have to store a lot more logic in our components, and we would like to follow best practices and use separate functions for that. In the next step we will see how we can do that.
In /src/index.js replace all code with the following:
import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
class App extends React.Component {
render() {
return (
<div>
<p>The button has been clicked 0 times</p>
<button>Click me!!!</button>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById("root")
);- notice the use of new ES6 syntax:
class,extends - all class components require a
render()method, it should return JSX
Props are still available in class components, but they are now part available throughout the class via this.props
...
class App extends React.Component {
render() {
return (
<div>
<p>The button has been clicked 0 times</p>
<button>{ this.props.btnText }!!!</button>
</div>
);
}
}
ReactDOM.render(
<App btnText="Click me" />,
document.getElementById("root")
);
...In our current example, our intent is to update the app with the number of times that the button has been pressed. We will do this by introducing two new concepts in the following two steps.
First, let's do something when the button is clicked.
class App extends React.Component {
render() {
return (
<div>
<p>The button has been clicked 0 times</p>
<button onClick={ (e) => alert('The button was pressed!') }>{ this.props.btnText }!!!</button>
</div>
);
}
}In regular HTML, we can use the attribute <div onclick="..."> to run some javascript event handling code. In react we will use the onClick prop instead.
- notice the camel casing of standard html attributes
className,onClickin react - onClick receives a function that will run in response to the event
- what happens if you change it to just
onClick={ alert('The button was pressed!) } onClickworks with other html tags, such as img, div, h1, etc.estands for event, it contains information about the user event, such as which mouse button was used to click.
Now that we can handle the events like a button being clicked, we want to keep track of how many times the user has clicked the button.
Props are immutable (read-only) so we cannot use them to do that. So now we introduce another core react object that is mutable, state.
class App extends React.Component {
constructor(props) {
super(props); // required so that props work
this.state = {
clicks: 0,
};
}
handleClick(event) {
this.setState({
clicks: this.state.clicks + 1
});
}
render() {
return (
<div>
<p>The button has been clicked { this.state.clicks } times</p>
<button onClick={ (e) => this.handleClick(e) }>{ this.props.btnText }!!!</button>
</div>
);
}
}In this example we initialize state in the constructor and update it in the handleClick function.
- the constructor receives the props
super(props)must be called in the constructor for class components to work properlythis.stateis initialized with an object, provide initial values to all state properties you will use.handleClickis our own function. We can call it anything we like.- state can only be updated with the
this.setState({...})property this.state.clicks = 42will not work as expected, try this.
Check out a similar and funny example: https://jsbin.com/xemiboniye/1/edit?html,js,output
Complete the lab in this repository: https://github.com/CUNYTechPrep/react-lab-1