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