Intro:
- Basics : components, events, templates, props and forms
- Router : routes, route paramenter, redirects
- Redux : stores,actions & reducers
Samples Git https://github.com/iamshaunjp/react-redux-complete-playlist
CDN Links https://reactjs.org/docs/cdn-links.html
VS Code extensions that could be handy
- ES7 React/Redux/GraphQL/React Native Snippets by dsznajder
- Sublime babel by josh peng
Browser extensions
React Developer tools by facebook firefox , Chrome
It is similar to developer tools, it helps to test react projects on the fly
JSX
Class Components
-
Class components extends React.Component
-
has
render()
method andstate
property(whichi is an object), which are speacial for React -
for accessing
this
in methods other than render, you need arrow functions eg:handleClick = (e) => {console.log(this.state.name);}
-
never update
state
directly. To updatestate
object , use the formatsetState({name: "new name"});
A basic Class component skelton is
import React, { Component } from 'react'
class MyReactClassComponent extends Component {
state = {
}
render(){
}
}
Few Limitations while using JSX
- component render should return html with only one root element
- in html keywords reserved in JS cannot be used. eg: instead of
class
,className
should be used for CSS classes - instead of
label.for
usehtmlFor
JSX to JS convertoer
http://www.babeljs.io/ >> Setup >> In browser
get this
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
and modify script
tag as <script type="text/babel"></script>
example code in https://github.com/iamshaunjp/react-redux-complete-playlist/blob/lesson-4/index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>React Basics</title>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
class App extends React.Component {
render(){
return(
<div className="app-content">
<h1>Hello, ninjas!</h1>
<p>Random number: { Math.random() * 10 }</p>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('app'));
</script>
</body>
</html>
Create React app
Default app Flow of Condrol
public/index.html -includes-> src/Index.js --renders Class Component App
imported from--> App.js
https://github.com/facebook/create-react-app
- Commandline tool
- Test server
- Keep code modular
- use build tools to create optimised code
- Enables use of ES6 code
- uses webpack to compile files
Pre requisite: Node must be installed.
You may simply install react first.
npm i react
OR
npm install react
AND then create react app
npx create-react-app my-app
cd my-app
npm start
PS: To stop server Use Ctrl + C
.
To run in apache
npm run build
Build for Development Environments
in development environment , if you are using a sub directory to develop and needs to test in the local server after you build, do the following steps as mentioned in the official create-react-app documentation
- Set the app homepage
Located in yourpackage.json
file is a property called homepage. The npm run build command that comes with create-react-app uses this property in order to make sure the production build points to the correct location.
"homepage": "https://myapp.com/directory-name",
If you are not using the HTML5 pushState history API or not using client-side routing at all just set "homepage": ".",
as mentioned here . Note: this feature is available with react-scripts@0.9.0 and higher (which can be checked in dependencies in package.json).
- Set the basename in
src/App.js
Setting the basename attribute on thecomponent tells React Router that the app will be served from a subdirectory.
<Router basename='/directory-name'>
<Route path='/' component={Home} />
{/* … */}
</Router>
to make it more versatile, you may use a variable to set basename
const basename = "/pjt/tests/ReactJS/build";
and use that variable in Router tag
<BrowserRouter basename={basename}>
RegisterServiceWorker in index.js is used for caching and thereby speeding up.
Single page apps(SPAs)
Only one page is served. React controlls what user sees
Nesting Components
- usually
App
is root component. - Other components are included into it.
- purpose is to keep code modular
- child components may have its own state or methode, which must not be meddled with parent/root component.
Types of import in JS
- Default Export(Import as any name) And
- Named Export(Import specifiv name in curly Braces)
eg:
import React from "react"
/* function Greet(){
return <h1>Hello World</h1>
} */
// this is default export
// default export could be imported in any name. eg: MyComponent
//ie import MyComponent from './components/Greet';
// Only condidtion is that tag whould be <MyComponent>
const Greet = ()=><h1>Hello World Arrow Function</h1>;
export default Greet
-----------------
/*
// this is named export
// named export should be imported as
// import {Greet} from './components/Greet';
export const Greet = ()=><h1>Hello World Arrow Function</h1>;
*/
Properties(props)
- Properties are used to pass data from parent component to child component.
- accessible with
this.props
inrender()
- could do
destructuring
eg: const {name,age,belt} = this.props;
Cycling though components
Use array.map
method for this.props.ninjas
Eg: https://github.com/iamshaunjp/react-redux-complete-playlist/blob/lesson-14/
class App extends Component {
state = {
ninjas: [
{ name: 'Ryu', age: 30, belt: 'black', id: 1 },
{ name: 'Yoshi', age: 20, belt: 'green', id: 2 },
{ name: 'Crystal', age: 25, belt: 'pink', id: 3 }
]
}
render() {
return (
<div className="App">
<h1>My first React app</h1>
<Ninjas ninjas={this.state.ninjas}/>
</div>
);
}
}
and in Ninjas Class
render(){
const { ninjas } = this.props;
const ninjaList = ninjas.map(ninja => {
return (
<div className="ninja" key={ninja.id}>
<div>Name: { ninja.name }</div>
<div>Age: { ninja.age }</div>
<div>Belt: { ninja.belt }</div>
</div>
)
});
return (
<div className="ninja-list">
{ ninjaList }
</div>
)
}
Container(Class) Vs UI(functional) Components
UI get data from props , doesnt have state
Eg: https://github.com/iamshaunjp/react-redux-complete-playlist/blob/lesson-15/
import React from 'react'
const Ninjas = ({ninjas}) => {
// const { ninjas } = props; // use this is paramenter passed is props instead of {ninjas}
const ninjaList = ninjas.map(ninja => {
return (
<div className="ninja" key={ninja.id}>
<div>Name: { ninja.name }</div>
<div>Age: { ninja.age }</div>
<div>Belt: { ninja.belt }</div>
</div>
)
});
return (
<div className="ninja-list">
{ ninjaList }
</div>
);
}
export default Ninjas
Conditional display
use if
or tertiary operator
https://github.com/iamshaunjp/react-redux-complete-playlist/blob/lesson-16/myapp/src/Ninjas.js
Handling Forms
Create a new class AddNinja
https://github.com/iamshaunjp/react-redux-complete-playlist/blob/lesson-17/myapp/src/AddNinja.js
Add it with <AddNinja />
tag in App.js https://github.com/iamshaunjp/react-redux-complete-playlist/blob/lesson-17/myapp/src/App.js
import React, { Component } from 'react';
import Ninjas from './Ninjas'
import AddNinja from './AddNinja'
class App extends Component {
state = {
ninjas: [
{ name: 'Ryu', age: 30, belt: 'black', id: 1 },
{ name: 'Yoshi', age: 20, belt: 'green', id: 2 },
{ name: 'Crystal', age: 25, belt: 'pink', id: 3 }
]
}
addNinja = (ninja) => {
ninja.id = Math.random();
let ninjas = [...this.state.ninjas, ninja];
this.setState({
ninjas: ninjas
});
}
render() {
return (
<div className="App">
<h1>My first React app</h1>
<Ninjas ninjas={this.state.ninjas}/>
<AddNinja addNinja={this.addNinja} />
</div>
);
}
}
export default App;
AddNinja.js
import React, { Component } from 'react'
class AddNinja extends Component {
state = {
name: null,
age: null,
belt: null,
}
handleChange = (e) => {
this.setState({
[e.target.id]: e.target.value
});
}
handleSubmit = (e) => {
e.preventDefault();
this.props.addNinja(this.state);
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<label htmlFor="name">Name:</label>
<input type="text" id="name" onChange={this.handleChange} />
<label htmlFor="age">Age:</label>
<input type="text" id="age" onChange={this.handleChange} />
<label htmlFor="belt">Belt:</label>
<input type="text"id="belt" onChange={this.handleChange} />
<button>Submit</button>
</form>
</div>
)
}
}
export default AddNinja
Calling parent component method from child component
Parent method is passed as a property to child component
https://github.com/iamshaunjp/react-redux-complete-playlist/blob/lesson-18/myapp/src/App.js
class App extends Component {
state = {
ninjas: [
{ name: 'Ryu', age: 30, belt: 'black', id: 1 },
{ name: 'Yoshi', age: 20, belt: 'green', id: 2 },
{ name: 'Crystal', age: 25, belt: 'pink', id: 3 }
]
}
addNinja = (ninja) => {
ninja.id = Math.random();
let ninjas = [...this.state.ninjas, ninja];
this.setState({
ninjas: ninjas
});
}
and
render() {
return (
<div className="App">
<h1>My first React app</h1>
<Ninjas ninjas={this.state.ninjas}/>
<AddNinja addNinja={this.addNinja} />
</div>
);
}
}
https://github.com/iamshaunjp/react-redux-complete-playlist/blob/lesson-18/myapp/src/AddNinja.js
In AddNinja
, App.addNinja method
will be available as this.props.addNinja
Deleting Data
https://www.youtube.com/watch?v=UmuLW78biBw&list=PL4cUxeGkcC9ij8CfkAY2RAGb-tmkNwQHG&index=19
https://github.com/iamshaunjp/react-redux-complete-playlist/blob/lesson-19/myapp/src/App.js>
deleteNinja = (id) => {
// console.log(id);
let ninjas = this.state.ninjas.filter(ninja => {
return ninja.id !== id
});
this.setState({
ninjas: ninjas
});
}
and
<Ninjas ninjas={this.state.ninjas} deleteNinja={this.deleteNinja} />
https://github.com/iamshaunjp/react-redux-complete-playlist/blob/lesson-19/myapp/src/Ninjas.js>
const Ninjas = ({ninjas, deleteNinja}) => {
return (
<div className="ninja-list">
{
ninjas.map(ninja => {
return (
<div className="ninja" key={ninja.id}>
<div>Name: { ninja.name }</div>
<div>Age: { ninja.age }</div>
<div>Belt: { ninja.belt }</div>
<button onClick={() => {deleteNinja(ninja.id)}}>Delete ninja</button>
<hr />
</div>
)
})
}
CSS
CSS files could be imported
import './Ninja.css';
https://github.com/iamshaunjp/react-redux-complete-playlist/blob/lesson-21/myapp/src/Ninjas.js>
Life Cycle Methods
Interactive Image https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/
Three phases where life cycle events are fired
- Mounting : constructer,render, componentDidMount
- Updating : setState, forceUpdate, render, componentDidUpdate
- Un Mounting : componentWillUnmount
Code at:
https://github.com/iamshaunjp/react-redux-complete-playlist/blob/lesson-22/myapp/src/App.js>
componentDidMount(){
console.log('component mounted');
}
componentDidUpdate(prevProps, prevState, snapshot){
console.log('component updated');
console.log(prevProps, prevState);
}
Simple to do App with what was learned so far
A react app with adds and deletes to do items
video, Part 1 Git
Add Materialize CSS in index.html, for using collection
and collection-item
classes.
and also
|
|