MODULE 3 - 4 [ REACT JS NOTES ] BASICS FOR ALL WEB DEVELOPMENT
React JS App Creation
Create React App
Create React App is a comfortable environment for learning React, and is the best way to start building a new single-page application in React.
It sets up your development environment so that you can use the latest JavaScript features, provides a nice developer experience, and optimizes your app for production. You’ll need to have Node >= 8.10 and npm >= 5.6 on your machine. To create a project, run:
npx create-react-app my-app
cd my-app
npm start
Note
npx on the first line is not a typo — it’s a package runner tool that comes with npm 5.2+.
Create React App doesn’t handle backend logic or databases; it just creates a frontend build pipeline, so you can use it with any backend you want. Under the hood, it uses Babel and a webpack, but you don’t need to know anything about them.
When you’re ready to deploy to production, running npm run build will create an optimized build of your app in the build folder
As said above when you are ready with your app all necessary files have been installed (package.json and all node modules including babel, webpack), run
npm start to execute the app.
React components
What are components?
Components are the building blocks of any React app and a typical React app will have many of these. Simply put, a component is a JavaScript class or function that optionally accepts inputs i.e. properties(props) and returns a React element that describes how a section of the UI (User Interface) should appear.
Your first component
const Greeting = () => <h1>Hello World today!</h1>;
This is a functional component (called Greeting) written using ES6’s arrow function syntax that takes no props and returns an H1 tag with the text “Hello World today!”
In order to run the code examples in this chapter on your machine, you first have to install a server globally using nodeJs. Below is the command to install the http-server on your machine. Open your terminal and run:-
npm install http-server -g
Your index.html should look like this at this point:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Get Started with Vumbula React</title>
</head>
<body>
<div id="root">
Loading...
</div>
<script src="https://unpkg.com/@babel/standalone/babel.js"></script>
<script src="https://unpkg.com/react/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>
<script type="text/babel">
// Add your brand new component here
const Greeting = () => <h1>Hello World today!</h1>;
ReactDOM.render(
<Greeting />,
document.getElementById('root')
);
</script>
</body>
</html>
=> The React script allows us to write React components
=> The ReactDOM script allows us to place our components and work with them in the context of the DOM
=> The Babel script allows us to transpile ES6 to ES5. Some browsers have limited support for ES6 features; transpiling our ES6 to ES5 allows us to use the modern features of ES6 in our design without having to worry about compatibility. Notice that the React code is wrapped in a script tag with a type of text/babel.
ReactDOM.render(<Greeting />, document.getElementById('root'));
Use ReactDOM’s render method to render the Greeting element into the DOM in a container with the id of root.
A different way to write components
So far, you’ve written a functional component, a fitting name since it really was just a function. Components can also be written using ES6 classes instead of functions. Such components are called class components. Go ahead and convert the functional Greeting component to a class component like so:
class Greeting extends React.Component {
render(){
return <h1>Hello World Today!</h1>;
}
}
Functional (Stateless) Vs Class (Stateful) components
By now, you’ve created both a functional and class component. In this section, we’ll take a closer look at the differences as well as situations in which you might prefer to use one type over another.
Functional components
These components are purely presentational and are simply represented by a function that optionally takes props and returns a React element to be rendered to the page.
Generally, it is preferred to use functional components whenever possible because of their predictability and conciseness. Since, they are purely presentational, their output is always the same given the same props.
You may find functional components referred to as stateless, dumb or presentational in other literature. All these names are derived from the simple nature that functional components take on.
=> Functional because they are basically functions
=> Stateless because they do not hold and/or manage state
=> Presentational because all they do is output UI elements
A functional component in it’s simplest form looks something like this:
const Greeting = () => <h1>Hi, I’m a functional component!</h1>;
Class Components
These components are created using ES6’s class syntax. They have some additional features such as the ability to contain logic (for example methods that handle onClick events), local state (more on this in the next chapter) and other capabilities to be explored in later sections of the book.
As you explore other resources, you might find class components referred to as smart, container or stateful components.
=> Class because they are basically classes
=> Smart because they can contain logic
=> Stateful because they can hold and/or manage local state
=> Container because they usually hold/contain numerous other (mostly functional) components
Class components have a considerably larger amount of markup. Using them excessively and unnecessarily can negatively affect performance as well as code readability, maintainability and testability.
A class component in its simplest form:
class Greeting extends React.Component {
render(){
return <h1>Hi, I’m a smart component!</h1>;
}
}
Props
Props are React’s way of making components easily and dynamically customisable. They provide a way of passing properties/data down from one component to another, typically from a parent to a child component (unidirectional data flow).
It’s important to note that props are read-only and that a component must never modify the props passed to it. As such, when a component is passed props as input, it should always return the same result for the same input.
const Greeting = props => <h1>Hello {props.name}</h1>;
ReactDOM.render(
<Greeting name={‘Edmond’}/>,
document.getElementById('root')
);
Using Props with Class Components
class Greeting extends React.Component {
render(){
return <h1>Hello {this.props.name}</h1>;
}
}ReactDOM.render(
<Greeting name={‘Edmond’}/>,
document.getElementById('root')
);
react-router
React Router is a powerful routing library built on top of React that helps you add new screens and flows to your application incredibly quickly, all while keeping the URL in sync with what's being displayed on the page.
Installation
Using npm:
$ npm install --save react-router
Ex: 1. Build an App.js React Component
In the src directory, create one component file called App.js and put the following code into it.
// App.js
import React, { Component } from 'react';
class App extends Component {
render() {
return (
<div>
<h2>Welcome to React Router Tutorial</h2>
</div>
);
}
}
export default App;
Now, in the main.js file, put the following into it.
// main.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('app'));
There are two types of router object:
BrowserRouter
HashRouter
If we want to handle the dynamic request then use BrowserRouter and if we want to serve the static request then use HashRouter.
This is how we can render the BrowserRouter object.
// main.js
import { BrowserRouter } from 'react-router-dom'
import App from './App';
ReactDOM.render((
<BrowserRouter>
<App />
</BrowserRouter>
), document.getElementById('root'))
2.Make three Component
First, make one components directory and in that make Home.js component.
// Home.js
import React, { Component } from 'react';
class Home extends Component {
render() {
return (
<div>
<h2>Home</h2>
</div>
);
}
}
export default Home;
//About.js
import React, { Component } from 'react';
class About extends Component {
render() {
return (
<div>
<h2>About</h2>
</div>
);
}
}
export default About;
// Contact.js
import React, { Component } from 'react';
class Contact extends Component {
render() {
return (
<div>
<h2>Contact</h2>
</div>
);
}
}
export default Contact;
3.Register the routes in the App.js file
// App.js
import React, { Component } from 'react';
import { BrowserRouter as Router, Switch, Route, Link } from 'react-router-dom';
import Home from './components/Home';
import About from './components/About';
import Contact from './components/Contact';
class App extends Component {
render() {
return (
<Router>
<div>
<h2>Welcome to React Router Tutorial</h2>
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<ul className="navbar-nav mr-auto">
<li><Link to={'/'} className="nav-link"> Home </Link></li>
<li><Linkto={'/contact'}className="nav-link">Contact</Link></li>
<li><Linkto={'/about'}className="nav-link">About</Link></li>
</ul>
</nav>
<hr />
<Switch>
<Route exact path='/' component={Home} />
<Route path='/contact' component={Contact} />
<Route path='/about' component={About} />
</Switch>
</div>
</Router>
);
}
}
export default App;
**.The final main.js file
// main.js
import React from 'react';
import { render } from 'react-dom';
import App from './App';
render(
<App />, document.getElementById('app'));
**.index.html file
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://fonts.googleapis.com/css?family=Open+Sans|Roboto" rel="stylesheet">
<link
rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
<title>React Router Tutorial</title>
</head>
<body>
<div id="App" class="container"></div>
</body>
</html>
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MODULE - 4
State is the place where the data comes from. We should always try to make our state as simple as possible and minimize the number of stateful components. If we have, for example, ten components that need data from the state, we should create one container component that will keep the state for all of them.
Using State
The following sample code shows how to create a stateful component using EcmaScript2016 syntax.
App.jsx
import React from 'react';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
header: "Header from state...",
content: "Content from state..."
}
}
render() {
return (
<div>
<h1>{this.state.header}</h1>
<h2>{this.state.content}</h2>
</div>
);
}
}
export default App;
The main difference between state and props is that props are immutable. This is why the container component should define the state that can be updated and changed, while the child components should only pass data from the state using props.
Using Props
When we need immutable data in our component, we can just add props to reactDOM.render() function in main.js and use it inside our component.
App.jsx
import React from 'react';
class App extends React.Component {
render() {
return (
<div>
<h1>{this.props.headerProp}</h1>
<h2>{this.props.contentProp}</h2>
</div>
);
}
}
export default App;
main.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';
ReactDOM.render(<App headerProp = "Header from props..." contentProp = "Content
from props..."/>, document.getElementById('app'));
export default App;
Default Props
You can also set default property values directly on the component constructor instead of adding it to the reactDom.render() element.
App.jsx
import React from 'react';
class App extends React.Component {
render() {
return (
<div>
<h1>{this.props.headerProp}</h1>
<h2>{this.props.contentProp}</h2>
</div>
);
}
}
App.defaultProps = {
headerProp: "Header from props...",
contentProp:"Content from props..."
}
export default App;
main.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';
ReactDOM.render(<App/>, document.getElementById('app'));
State and Props
The following example shows how to combine state and props in your app. We are setting the state in our parent component and passing it down the component tree using props. Inside the render function, we are setting headerProp and contentProp used in child components.
App.jsx
import React from 'react';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
header: "Header from props...",
content: "Content from props..."
}
}
render() {
return (
<div>
<Header headerProp = {this.state.header}/>
<Content contentProp = {this.state.content}/>
</div>
);
}
}
class Header extends React.Component {
render() {
return (
<div>
<h1>{this.props.headerProp}</h1>
</div>
);
}
}
class Content extends React.Component {
render() {
return (
<div>
<h2>{this.props.contentProp}</h2>
</div>
);
}
}
export default App;
main.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';
ReactDOM.render(<App/>, document.getElementById('app'));
The result will again be the same as in the previous two examples, the only thing that is different is the source of our data, which is now originally coming from the state. When we want to update it, we just need to update the state, and all child components will be updated
Validating Props
In this example, we are creating App component with all the props that we need. App.propTypes is used for props validation. If some of the props aren't using the correct type that we assigned, we will get a console warning. After we specify validation patterns, we will set App.defaultProps.
App.jsx
import React from 'react';
class App extends React.Component {
render() {
return (
<div>
<h3>Array: {this.props.propArray}</h3>
<h3>Bool: {this.props.propBool ? "True..." : "False..."}</h3>
<h3>Func: {this.props.propFunc(3)}</h3>
<h3>Number: {this.props.propNumber}</h3>
<h3>String: {this.props.propString}</h3>
<h3>Object: {this.props.propObject.objectName1}</h3>
<h3>Object: {this.props.propObject.objectName2}</h3>
<h3>Object: {this.props.propObject.objectName3}</h3>
</div>
);
}
}
App.propTypes = {
propArray: React.PropTypes.array.isRequired,
propBool: React.PropTypes.bool.isRequired,
propFunc: React.PropTypes.func,
propNumber: React.PropTypes.number,
propString: React.PropTypes.string,
propObject: React.PropTypes.object
}
App.defaultProps = {
propArray: [1,2,3,4,5],
propBool: true,
propFunc: function(e){return e},
propNumber: 1,
propString: "String value...",
propObject: {
objectName1:"objectValue1",
objectName2: "objectValue2",
objectName3: "objectValue3"
}
}
export default App;
main.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';
ReactDOM.render(<App/>, document.getElementById('app'));
Forms
In the following example, we will set an input form with value = {this.state.data}. This allows us to update the state whenever the input value changes. We are using an onChange event that will watch the input changes and update the state accordingly.
App.jsx
import React from 'react';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
data: 'Initial data...'
}
this.updateState = this.updateState.bind(this);
};
updateState(e) {
this.setState({data: e.target.value});
}
render() {
return (
<div>
<input type = "text" value = {this.state.data}
onChange = {this.updateState} />
<h4>{this.state.data}</h4>
</div>
);
}
}
export default App;
main.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';
ReactDOM.render(<App/>, document.getElementById('app'));
Complex Example
In the following example, we will see how to use forms from child component. onChange method will trigger state update that will be passed to the child input value and rendered on the screen. A similar example is used in the Events chapter. Whenever we need to update state from child component, we need to pass the function that will handle updating (updateState) as a prop (updateStateProp).
App.jsx
import React from 'react';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
data: 'Initial data...'
}
this.updateState = this.updateState.bind(this);
};
updateState(e) {
this.setState({data: e.target.value});
}
render() {
return (
<div>
<Content myDataProp = {this.state.data}
updateStateProp = {this.updateState}></Content>
</div>
);
}
}
class Content extends React.Component {
render() {
return (
<div>
<input type = "text" value = {this.props.myDataProp}
onChange = {this.props.updateStateProp} />
<h3>{this.props.myDataProp}</h3>
</div>
);
}
}
export default App;
main.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';
ReactDOM.render(<App/>, document.getElementById('app'));
The ref is used to return a reference to the element. Refs should be avoided in most cases, however, they can be useful when we need DOM measurements or to add methods to the components.
Using Refs
The following example shows how to use refs to clear the input field. ClearInput function searches for element with ref = "myInput" value, resets the state, and adds focus to it after the button is clicked.
App.jsx
import React from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
data: ''
}
this.updateState = this.updateState.bind(this);
this.clearInput = this.clearInput.bind(this);
};
updateState(e) {
this.setState({data: e.target.value});
}
clearInput() {
this.setState({data: ''});
ReactDOM.findDOMNode(this.refs.myInput).focus();
}
render() {
return (
<div>
<input value = {this.state.data} onChange = {this.updateState}
ref = "myInput"></input>
<button onClick = {this.clearInput}>CLEAR</button>
<h4>{this.state.data}</h4>
</div>
);
}
}
export default App;
main.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';
ReactDOM.render(<App/>, document.getElementById('app'));
React keys are useful when working with dynamically created components or when your lists are altered by the users. Setting the key value will keep your components uniquely identified after the change.
Using Keys
Let's dynamically create Content elements with unique index (i). The map function will create three elements from our data array. Since the key value needs to be unique for every element, we will assign it as a key for each created element.
App.jsx
import React from 'react';
class App extends React.Component {
constructor() {
super();
this.state = {
data:[
{
component: 'First...',
id: 1
},
{
component: 'Second...',
id: 2
},
{
component: 'Third...',
id: 3
}
]
}
}
render() {
return (
<div>
<div>
{this.state.data.map((dynamicComponent, i) => <Content
key = {i} componentData = {dynamicComponent}/>)}
</div>
</div>
);
}
}
class Content extends React.Component {
render() {
return (
<div>
<div>{this.props.componentData.component}</div>
<div>{this.props.componentData.id}</div>
</div>
);
}
}
export default App;
main.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.jsx';
ReactDOM.render(<App/>, document.getElementById('app'));
Fragments:
It's common pattern in React which is used for a component to return multiple elements. Fragments let you group a list of children without adding extra nodes to the DOM.
Ex:
render() {
return (
<React.Fragment>
<ChildA />
<ChildB />
<ChildC />
</React.Fragment>
)
}
Comments
Post a Comment