React Development Basics

Intro:

  1. Basics : components, events, templates, props and forms
  2. Router : routes, route paramenter, redirects
  3. 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

  1. ES7 React/Redux/GraphQL/React Native Snippets by dsznajder
  2. 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

  1. Class components extends React.Component

  2. has render() method and state property(whichi is an object), which are speacial for React

  3. for accessing this in methods other than render, you need arrow functions eg: handleClick = (e) => {console.log(this.state.name);}

  4. never update state directly. To update state object , use the format setState({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

  1. component render should return html with only one root element
  2. in html keywords reserved in JS cannot be used. eg: instead of class , className should be used for CSS classes
  3. instead of label.for use htmlFor

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

  1. Commandline tool
  2. Test server
  3. Keep code modular
  4. use build tools to create optimised code
  5. Enables use of ES6 code
  6. 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

visithttp://localhost:3000/

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

  1. Set the app homepage
    Located in your package.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).

  1. Set the basename in src/App.js
    Setting the basename attribute on the component 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

  1. usually App is root component.
  2. Other components are included into it.
  3. purpose is to keep code modular
  4. child components may have its own state or methode, which must not be meddled with parent/root component.

Types of import in JS

  1. Default Export(Import as any name) And
  2. 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)

  1. Properties are used to pass data from parent component to child component.
  2. accessible with this.props in render()
  3. could do destructuring eg: const {name,age,belt} = this.props;

Cycling though components

Tutorial 14

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/

Git of Diagram

React Life Cycle Methods

Three phases where life cycle events are fired

  1. Mounting : constructer,render, componentDidMount
  2. Updating : setState, forceUpdate, render, componentDidUpdate
  3. 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

Part 2 Git