React Deeper Dive 2

React Deeper Dive 2

Routing

Routing in react is carried out by react-router-dom. The react router helps to build single page applications to effortlessly transition between different sections of the website.

React router helps in navigation of various react components.

Let's look at an example.

Create a react app having these files.

// Dashboard.jsx

import React from 'react'

function Dashboard() {
  return (
    <div>
      Dashboard
    </div>
  )
}

export default Dashboard
// Landing.jsx

import React from 'react'

function Landing() {
  return (
    <div>
      Landing
    </div>
  )
}

export default Landing

Use Command "npm i react-router-dom" .

We need to import these libraries in our App.jsx file.

// App.jsx
import {BrowserRouter, Routes, Route} from "react-router-dom"
import Dashboard from './Dashboard';
import Landing from './Landing';

function App(){
    return(
        <>
            <BrowserRouter>
                <Routes>
                      <Route path = "/landing" element = {<Landing/>}/>
                      <Route path = "/dashboard" element = {<Dashboard/>}/>
                </Routes>
            </BrowserRouter>
        </>

    )

}

export default App

Using useNavigate Hook

This hook helps to navigate programmatically between routes in a react application.

import { BrowserRouter, Route, Routes, useNavigate } from "react-router-dom"
import Landing from "./Landing"
import Dashboard from "./Dashboard"



function App(){
  return(
    <>
      <BrowserRouter>
      <Appbar/>
        <Routes>
          <Route path='/landing' element={<Landing/>}/>
          <Route path='/dashboard' element={<Dashboard/>}/>
        </Routes>
      </BrowserRouter>
    </>
  )

}

function Appbar(){
  const navigate = useNavigate()

  return(
    <>
      <button onClick={() => {navigate('/landing')}}>Landing</button>
      <button onClick={() => {navigate('/dashboard')}}>Dashboard</button>
    </>
  )
}
export default App

Using Lazy Loading

Lazy loading in React allows you to load components only when they are needed, which can significantly improve the performance of your application by reducing the initial load time. This is particularly useful for large applications with many routes or components.

import {BrowserRouter, Routes, Route} from 'react-router-dom'
import React from 'react';

const Dashboard = React.lazy(()=>import('./Dashboard'));
const Landing = React.lazy(()=>import('./Landing'));

function App() {

  return (
    <>
     <BrowserRouter>  
      <Routes>
        <Route path='/dashboard' element={<Dashboard/>}/>
        <Route path='/landing' element={<Landing/>}/>
      </Routes>
    </BrowserRouter>
    </>
  )
}
export default App

Prop Drilling

Prop drilling is basically a situation when the same data is being sent at almost every level due to requirements in the final level.

This gets very hard to maintain and highly verbose. Makes code highly unreadable.

import { useState } from "react"

function App(){
  const[message, setMessage] = useState("Hello world")

  return(
    <div>
      <h6>Parent Prop</h6>
      <Child1Prop message={message}/>
    </div>
  )
}

function Child1Prop({message}){
  return(
    <div>
      <h6>Child1</h6>
      <Child2Prop message={message}/>
    </div>
  )
}

function Child2Prop({message}){ 
  return(
    <div>
      <h1>{message}</h1>
    </div>
  )
}

export default App

It shows the syntactic uneasiness when writing code.

Context API

Prop drilling can be avoided by using state management solutions like Context API which allows for more direct state access without having to pass props through many layers of components.

Let's look at an example. Create the following files.

// Context.jsx

import { createContext } from "react";

export const MessageContext = createContext('Hello world')
// App.jsx

import { useContext, useState } from "react"
import { MessageContext } from "./Context"

function App(){
  const[message, setMessage] = useState("Hello world")

  return(
    <div>
      <h6>Parent Prop</h6>
      <MessageContext.Provider value={{message, setMessage}}>
      <Child1Prop/>
      </MessageContext.Provider>
    </div>
  )
}

function Child1Prop(){
  return(
    <div>
      <h6>Child1</h6>
      <Child2Prop/>
    </div>
  )
}

function Child2Prop(){ 
  const {message} = useContext(MessageContext)
  return(
    <div>
      <h1>{message}</h1>
    </div>
  )
}

export default App

Did you find this article valuable?

Support Reuben's blog by becoming a sponsor. Any amount is appreciated!