Back reactions with ReactJS
Target :4th Year (Advanced Web)
Simple but efficient introduction to ReactJS that is designed to create interactive UIs.React is often referred to as the View in a MVC architecture:
React = V
I- Init
After installation of ReactJS:
@matrix: sudo npm install -g create-react-app.
Create the skeleton of your first ReactJS app:
@matrix: create-react-app insa-app
The skeleton of our first app:
II- SPA
React JS is a JS library for Single-Page Application.
The Single pages is the page index.html
We will take a look to index.html ( folder /public):
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico"> <title>React App</title> </head> <body> <div id="root"></div> </body> </html>
That's it. All the future content will take place here ( div with id=root):
<div id="root"> (here) </div>
To execute the application ( testing with integrated web server):
NB: nmp start will compile (transpile) your code before starting a web dev server for testing
The single page is displaying something!
Recall that index.html has one single and empty div element in its body. where this content is coming from ?
III- The V model
The model-view architecture: The V is the page index.js
The page index.js listens to changes and re-render in the static page index.html (the template)
Take a look at the view index.js :
//INDEX.JS
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css';
ReactDOM.render(
<App />,
document.getElementById('root')
);
The UI component App and its associated tag (<App/>) are defined in App.js.
React is responsible for rendering HTML content to the web page index.html by using a function called ReactDOM.render().
The code of App.js :
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
</div>
);
}
}
export default App;
The page App.js defines a UI component called App. You always should implement the method render.As the name suggests it handles the rendering of your component to the UI. You're not writing HTML in render method, you're writing JSX, which is compiled into Javascript.
Putting all together:
Note the render cycle: App will render to index.js and index.js will render to index.html
IV- UI Comment component
As simple exercise , let us add a comment block to the main page.
Create the folder src/Comment. In this folder, create the component Comment:
import React, { Component } from 'react';
class Comment extends Component {
render() {
return (
<div>
<textarea className="form-control" placeholder="Write a comment..."/>
<p><small>300 characters Remaining</small> </p>
</div>
)
}
}
export default Comment;
Modify the component App :
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Comment from './Comment/Comment';
class App extends Component {
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
<h3>Please comment on our simple app</h3>
<Comment/>
</div>
);
}
}
export default App;
V- Props and state
We have by now the following relationships:
The component Comment is considered as a sub-component of App component (Because App in our case instantiates Comment).
What if we need that the super-component App communicate information to its child Comment:
In App.js you do a small change:
<h3>Please comment on our simple app</h3>
<Comment maxLetters={280} />
In Comment.js:
<textarea className="form-control" placeholder="Write a comment..."/>
<p><small>{this.props.maxLetters} Remaining</small> </p>
the keyword props: props are some kind of HTML attributes.props are a way of passing data from parent to child!
Props is a JS object set by the parent component.
Once set, the props cannot be changed
Let us talk about the State of an UI component:
Consider again the supr component App. I modified it a bit
maxLetters and commentBy ar Props passed by App component to the child Comment Component.
I do need to count the number characters the user has typed. I will consider a counter of characters as part of Comment Component's state.The state of a component is a JS object.When the state object changes, the component re-renders. The state object stores the properties that belong to the component.
State object is generally updated by event handlers.Let us see the Comment component:
Before showing the modified code for Comment, I will show you the goal of this modification: I start by typing some letters in the input box (20 characters max, 2 remaining):
After typing more than 19 characters, the checkbox is checked:
and now the Comment.js code:
Some remarks about the above code:
- State object could be considered as the data model of the component ( where data comes from to UI component)
- To change the component state ( see computchar() method), you should use the predefined method setState.
- When the state object changes, the component re-renders (calling render method)
- JSX expression are close to Javascript expressions
- You cannot modify the component state within the method render().
VI- Routes in React
Here We will suppose that we have an Express Application listening at the port 8800.We suppose also the Express route/endpoint /user/login responds to client request of type POST.
A) Defining Login.js Component
import React from "react";
import API from "../API/api";
export class Login extends React.Component {
state = {
email: "",
password: ""
};
send = async () => {
const { email, password } = this.state;
try {
const { data } = await API.login(email, password);
} catch (error) {
console.error(error);
}
};
handleChange = (event) => {
this.setState({
[event.target.id]: event.target.value
});
};
render() {
const { email, password } = this.state;
return (
<div>
<form>
<div>
Email:
<input
id="email"
type="text"
value={email}
onChange ={this.handleChange}
/>
</div>
<div>
Password: <input
type="text"
id="password"
value={password}
onChange ={this.handleChange}
type="password"
/>
</div>
<input onClick ={this.send} type="submit" value="Submit" />
</form>
</div>
);
}
}
B) Defining api.js
api.js is just a script to send AJAX request to Express server
import axios from "axios";
const headers = {
"Content-Type": "application/json"
};
const burl = "http://localhost:8800";
export default {
login: function (email, password) {
return axios.post(
`${burl}/user/login`,
{
email,
password
},
{
headers: headers
}
);
}
};
C) Defining routes in App component
In App, with the help of two components (Switch and Route) we match React Routes with Express Routes ( Here we matched /login with UI Login Component)
D) Index.js
the component Route responsibility is to render some UI when its path matches the current URL.
The component BrowerRouter responsibility is to keep your UI in sync with the URL
finally: