React

React

React is a JavaScript library for building user interfaces create by Facebook. It is used to build single page applications. It allows us to create reusable UI components of mobile and web applications.

Supports server-side rendering.


Use of the virtual DOM rather than real DOM (Data Object Model) as RealDOM manipulations are expensive.


Follows unidirectional data binding or data flow.


Uses reusable or composable UI components for developing the view.

 

To find more details please visit react

Setup

To install and work on React we require following tools


Node.js down load from this link

It is free to use and run-on various platforms (Windows, Linux, UNIX, Mac, etc.)


IDE for writing our code. download from this Visual Studio

Start New Project

To work on react app first run following command in node.js to get React Environment.

npm install -g create-react-app


Run this command to create a React application named myfirstreact:

npm create-react-app myfirstreact


The create-react-app will set up everything you need to run a React application.

Run this command to move to the myfirstreact directory:

cd myfirstreact


Run this command to execute the React application myfirstreact:

npm start


A new browser window will pop up with your newly created React App! If not, open your browser and type localhost:3000 in the address bar.

First React functional Component


(src/App.js)

// React component


function App(){

    return <h1>Hello World</h1>

  }

 

  export default App;

How this component get render to the browser? The main project file is src/index.js and in that file there are instruction to render the component

ReactDOM.render(<App />, document.getElementById('root'))

The App component will then be rendered inside public/index.html 'root' div

Import Component

Component will be created in separate files. Each component need to be export and then import

function Greeting(){

    return <h1>Hello World</h2>

}

export default Greeting

This component can then be import

import Greeting from './Greeting'

 

function App(){

    return <Greeting />

}

or name export...

export function Greeting(){

    return <h1>Hello World</h2>

}

This component can then be import

import {Greeting} from './Greeting'

BEM Naming Convention

return (

    <div className="app">

      <h1 className="app_title">Welcome to my application: {appTitle}</h1>

      <div className="product">

        <h1 className="product__name--large">Product name: {product.name}</h1>

    <h1 className="product__name--small">Nick name: {product.nickName}</h1>

        <p className="product__description">Product description: {product.description}

      </div>

    <div>

    )

JSX Rules

Return a single element (only one parent element)

// not valid

return <h1>Hello world</h1><h2>Hi!</h2>

 

// valid with fragment.

return (

    <>

        <h1>Hello World</h1>

        <h2>Hi!</h2>

    </>

)

// Noted the parenthesis for multi-line formatting

Use className instead of class

Also all attribute name need to be camelCase

// not valid

return (

    <div class="title">

        Hello World

    </div>

)

 

// valid

return (

    <div className="title">

    </div>

)

Close every element

return (

    <img src="http:example.com/image.jpg" />

    <input type="text" name="first_name" />

)

Nested Components

// Arrow function shorthand component

const Person = () => <h1>ken wil</h1>

 

// Arrow function component

const Message = () => {

    return <h1>Hello</h1>

}

 

// Function component

function HelloWorld(){

  return (

      <>

          <Message />

          <Person />

      </>

  )

}

Component CSS

(src/App.css)

h1 {

    color: red;

}

(src/App.js)

Import the CSS file

import './App.css'

 

function App(){

  return <h1>Hello World</h1>

}

Inline CSS

function App(){

    return <h1 style={{ color: 'red' }}>Hello World</h1>

  }

Javascript in JSX


function App(){

    const name = 'ken'

    return (

      <>

          <h1>Hello {name}</h1>

          <p>{name === 'ken' ? '(admin)': '(user)'}</p>

      </>

    )

}

Component Properties (Props)

function App()

    return <Person name='ken' age={45} />

}

 

const Person = (props) => {

    return <h1>Name: {props.name}, Age: {props.age}</h1>

}

 

// or props object deconstructing

const Person = ({name, age}) => {

    return <h1>Name: {name} Age: {age}</h1>

}

Children Props (slot)

function App()

    return (

        <Person name='Mike' age={45}>

            Hi, this is a welcome message

        </Person>

    )

}

 

const Person = (props) => {

    return (

        <h1>Name: {props.name}, Age: {props.age}</h1>

        <p>{props.children}</p>

    )

}

 

// or props object deconstructing

const Person = ({name, age, children}) => {

    return (

        <h1>Name: {name} Age: {age}</h1>

        <p>{children}</p>

    )

}

Default Props value

const Person = ({name, age, children}) => {

    return (

        <h1>Name: {name} Age: {age}</h1>

        <p>{children}</p>

    )

}

 

Person.defaultProps = {

    name: 'No name',

    age: 0,

}

List

const people = [

    {id: 1, name: 'Ken', age: 45},

    {id: 2, name: 'Bee', age: 43},

    {id: 3, name: 'Eri', age: 47},

  ]

  function App(){

      return (

          people.map(person => {

              return <Person name={person.name} age={person.age}/>

          })

      )

  }

 

  const Person = (props) => {

    return (

        <h1>Name: {props.name}, Age: {props.age}</h1>

    )

  }

List with key (for React internal reference)

function App(){

    return (

        people.map(person => {

            return <Person key={person.id} name={person.name} age={person.age}/>

        })

     )

}

Props object destructuring

function App(){

    return people.map(person => <Person key={person.id} {...person} />)

  }

 

  const Person = ({name, age}) => {

    return (

        <h1>Name: {name}, Age: {age}</h1>

    )

  }

Click Event

const clickHandler = () => alert('Hello World')

function App(){

    return (

        <>

            <h1>Welcome to my app</h1>

            <button onClick={clickHandler}>Say Hi</button>

        </>

    )

}

or inline...

function App(){

    return (

        <>

            <h1>Welcome to my app</h1>

            <button onClick={ () => alert('Hello World') }>Say Hi</button>

        </>

     )

}

To pass arguments we need to use arrow function

const clickHandler = (message) => alert(message)

function App(){

    return (

        <>

            <h1>Welcome to my app</h1>

            <button onClick={() => clickHandler('Hello World')}>Say Hi</button>

        </>

    )

}

e for event arguments

const clickHandler = (e) => console.log(e.target)

function App(){

    return (

        <>

            <h1>Welcome to my app</h1>

            <button onClick={(e) => clickHandler(e)}>Say Hi</button>

        </>

    )

}

 

Or

 

const clickHandler = (e) => console.log(e.target)

function App(){

    return (

        <>

            <h1>Welcome to my app</h1>

            <button onClick={clickHandler}>Say Hi</button>

        </>

    )

}

 

Pass event from child to parent

function Todo({item, onDelete}) {

    return (

      <div>

        {item}

        <button onClick={() => onDelete(item)}

      </div>

    )

}

 

function Todos() {

  const handleDelete = (todo) => {

    const newTodos = todos.filter(item => item !== todo)

    setTodos(() => newTodos)

  }

 

  return (

    {todos.map(todo => (

       <Todo item={todo} onDelete={handleDelete}/>

    }

  )

}

useState Hook

The purpose of useState is to handle reactive data. any data that changes in the application is called state. And when the state changes, you want react to update the UI.



import React, {useState} from 'react';

 

const DisplayTitle = () => {

  const [title, setTitle] = useState('This is the Title')

  const handleClick = () => setTitle('New Title')

  return <>

    <h2>{title}</h2>

    <button type="button" className="btn" onClick={handleClick}>

      Change Title

    </button>

  </>

};

 

export default DisplayTitle;

useState with object

const DisplayTitle = () => {

    const [person, setPerson] = useState({name: 'Ken', age: 45})

    const handleClick = () => setPerson({...person, age: 49})

    return <>

      <h2>{title}</h2>

      <button type="button" className="btn" onClick={handleClick}>

        Change Age

      </button>

    </>

  };

setState functional form

function Counter() {

    const [count, setCount] = useState(0)

    // Use a function to set State

    const increase = () => setCount(() => count + 1)

    return (

      <>

        <h1>Counter</h1>

        <p>{count}</p>

        <button onClick={increase} className='btn'> + </button>

        <button onClick={() => setCount(() => count - 1)} className='btn'> - </button>

      </>

    )

  }

useEffect

In React you may want to execute code after lifecycle events or side effects.

By default useEffect function is execute after every re-render. You can then execute code everytime component update.

import React, { useEffect } from 'react';

 

function IncreaseValue() {

    const [value, setValue] = useState(0)

    useEffect(() => {

        document.title = `New value: ${value}`

    })

    return <button onClick={() => setValue(value + 1)}>Increase</button>

}

Conditional useEffect

Conditional need to be place inside useEffect function

useEffect(() => {

    if (value > 0) {

        document.title = `New value: ${value}`

    }

})

useEffect Dependency List

What if you want to execute code only on first render or only when a particular state change? You can use the useEffect function and send an array of dependencies as parameter.

useEffect will run only if state is in the Dependency List.

If the list is empty [] the useEffect will only run on initial render.

useEffect(() => {

    document.title = `New value: ${value}`

}, [])

// Noted the empty array. useEffect will then only run once on initial render

 

useEffect(() => {

    document.title = `New value: ${value}`

}, [value])

// Will run each time 'value' state change.


useEffect cleanup function

What if you want to execute code each time the component unmount?

To execute code only when a component is unmount/destroy you need to add a 'return' statement to your useEffect function.

useEffect(() =>  {

    const timer = window.setInterval(() => {

        setCount(count => count + 1)

    }, 1000)

    return () => clearInterval(timer)

}, [])

The code 'clearInterval(timer)' will only be execute before component is remove from UI (unmount)

Conditional Rendering

function DisplayGreeting() {

    const [name, setName] = useState('Ken')

    if (name === 'Ken') {

        return <h1>Hello admin {name}</h1>

    }

    return <h1>Hello user {name}</h1>

}

Inline If-Else

return (

    <div>

      The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.

    </div>

  );

}

Inline Logical && Operator.

Display only if first expression is truthy

truthy = Not : 0, "", null, undefined, and NaN

function DisplayUserInfo({active}) {

    return (

      <div>

        { active && <h1>User is active</h1>}

      </div>

    );

}

Multiple inline If

<span className={count === 0 && 'text-gray-500' || count > 0 && 'text-green-500' || count < 0 && 'text-red-500'}>{count}</span>

Form

const UserForm = () => {

    const [userName, setUserName] = useState('')

    const handleSubmit = (e) => {

      e.preventDefault()

      console.log(userName)

    }

  return (

  <>

      <form onSubmit={handleSubmit}>

        <input

            value={userName}

            onChange={(e) => setUserName(e.target.value)}

            type="text" id="userName"

            name="userName"

        />

         <button type="submit">Submit</button>

      </form>

  </>

  )

  };

 

  export default UserForm;

useRef

useRef is mostly use to target a DOM element. But it can also be use to keep/preserve a mutable value between each render. useRef does not trigger a re-render (like a useState).

const UseRefBasics = () => {

    const refContainer = useRef(null)

    const handleSubmit = (e) => {

      e.preventDefault()

      console.log(refContainer.current.value)

    }

 

    useEffect(() => {

      refContainer.current.focus()

    }, [])

 

    return (

      <div>

        <form className="form" onSubmit={handleSubmit}>

          <div>

            <input ref={refContainer} type="text" />

            <button type="submit">Submit</button>

          </div>

        </form>

      </div>

    )

  };