Setting Up the Development Environment
Prerequisites
- Node.js (>=12.x)
- npm (comes with Node.js)
Instructions
Step 1: Install Node.js
node -v
npm -v
Step 2: Create a New React Project
npx create-react-app my-scalable-architecture
cd my-scalable-architecture
Step 3: Set Up Project Structure
src/
, create folders for components, containers, and services:
mkdir src/components src/containers src/services
Step 4: Install Required Dependencies
npm install axios react-router-dom
Step 5: Run the Development Server
npm start
http://localhost:3000
.Step 6: Version Control
- Initialize a git repository:
git init
git add .
git commit -m "Initial commit"
This setup ensures you have a working development environment for your React-based scalable architecture project.
Component-Based Design Implementation in React
Directory Structure
/src
/components
/Button
- Button.js
- Button.css
/Header
- Header.js
- Header.css
/Footer
- Footer.js
- Footer.css
App.js
index.js
index.css
Component: Button
Button.js
import React from 'react';
import './Button.css';
const Button = ({ onClick, label }) => {
return (
);
};
export default Button;
Button.css
.custom-button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
}
Component: Header
Header.js
import React from 'react';
import './Header.css';
const Header = ({ title }) => {
return (
{title}
);
};
export default Header;
Header.css
.app-header {
background-color: #282c34;
padding: 20px;
color: white;
text-align: center;
}
Component: Footer
Footer.js
import React from 'react';
import './Footer.css';
const Footer = () => {
return (
);
};
export default Footer;
Footer.css
.app-footer {
background-color: #282c34;
padding: 10px;
color: white;
text-align: center;
position: fixed;
bottom: 0;
width: 100%;
}
Main Application
App.js
import React from 'react';
import Header from './components/Header/Header';
import Footer from './components/Footer/Footer';
import Button from './components/Button/Button';
import './App.css';
const App = () => {
const handleClick = () => {
alert('Button Clicked!');
};
return (
);
};
export default App;
App.css
.App {
text-align: center;
}
main {
padding: 20px;
}
Entry Point
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
ReactDOM.render(
,
document.getElementById('root')
);
index.css
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
}
State Management with Context API in React
Context Setup
1. Create a Context
// src/contexts/AppContext.js
import React, { createContext, useState } from 'react';
export const AppContext = createContext();
export const AppProvider = ({ children }) => {
const [state, setState] = useState({ key: 'value' });
return (
{children}
);
};
2. Wrap Application with Context Provider
// src/App.js
import React from 'react';
import { AppProvider } from './contexts/AppContext';
import SomeComponent from './components/SomeComponent';
function App() {
return (
);
}
export default App;
Consuming Context
3. Consume the Context in a Component
// src/components/SomeComponent.js
import React, { useContext } from 'react';
import { AppContext } from '../contexts/AppContext';
const SomeComponent = () => {
const { state, setState } = useContext(AppContext);
const updateState = () => {
setState({ key: 'new value' });
};
return (
{state.key}
);
};
export default SomeComponent;
### Notes
The code provided demonstrates:
1. How to create a context and provider using `createContext` and `useState`.
2. How to wrap the entire application using the context provider.
3. How to consume and manipulate the context state within a component.
This setup enables scalable state management suitable for a React application.
```javascript
// src/App.js
import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Home from './components/Home';
import About from './components/About';
import User from './components/User';
import NotFound from './components/NotFound';
function App() {
return (
);
}
export default App;
// src/components/Home.js
import React from 'react';
const Home = () => {
return Home Page
;
};
export default Home;
// src/components/About.js
import React from 'react';
const About = () => {
return About Page
;
};
export default About;
// src/components/User.js
import React from 'react';
import { useParams } from 'react-router-dom';
const User = () => {
let { id } = useParams();
return User ID: {id}
;
};
export default User;
// src/components/NotFound.js
import React from 'react';
const NotFound = () => {
return 404 - Not Found
;
};
export default NotFound;
This implementation involves creating dynamic routes in a React application using React Router. It includes a main App
component that sets up the router, different components for each route, and dynamic routing based on user ID.
Optimizing Performance and Scalability in React Components
Code Splitting with React.lazy and Suspense
// Load components lazily with React.lazy
const SomeComponent = React.lazy(() => import('./SomeComponent'));
// Use Suspense to wrap lazy-loaded components
function App() {
return (
<React.Suspense fallback={Loading...}>
);
}
Memoization with React.memo and useMemo
// Memoize functional components with React.memo
const MyComponent = React.memo(function MyComponent({ prop1, prop2 }) {
return (
{prop1} - {prop2}
);
});
// Memoize values with useMemo
const MemoizedValue = ({ a, b }) => {
const value = React.useMemo(() => {
return expensiveCalculation(a, b);
}, [a, b]);
return {value};
};
useCallback to Prevent Re-Renders
const ParentComponent = () => {
const [count, setCount] = React.useState(0);
// useCallback to memoize the function
const increment = React.useCallback(() => {
setCount((c) => c + 1);
}, []);
return (
{count}
);
};
const ChildComponent = React.memo(({ increment }) => {
console.log('Child component re-rendered');
return ;
});
Dynamic Import for Routes
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
const Home = React.lazy(() => import('./Home'));
const About = React.lazy(() => import('./About'));
function App() {
return (
<React.Suspense fallback={Loading...}>
);
}
Leveraging Concurrent Mode (Experimental)
import { createRoot } from 'react-dom/client';
const root = createRoot(document.getElementById('root'));
root.render(
);
Optimizing Performance with useTransition
const MyComponent = () => {
const [startTransition, isPending] = React.useTransition();
const [value, setValue] = React.useState('');
const handleChange = (e) => {
const newValue = e.target.value;
startTransition(() => {
setValue(newValue);
});
};
return (
{isPending && Loading...}
{value}
);
};
Avoiding Prop Drilling with Context API
const ThemeContext = React.createContext('light');
const ParentComponent = () => (
);
const ChildComponent = () => {
const theme = React.useContext(ThemeContext);
return Current theme: {theme};
};
Request Caching with SWR (Stale-While-Revalidate)
import useSWR from 'swr';
const fetcher = (url) => fetch(url).then((res) => res.json());
const MyComponent = () => {
const { data, error } = useSWR('/api/data', fetcher);
if (error) return Error: {error.message};
if (!data) return Loading...;
return Data: {JSON.stringify(data)};
};
Conclusion
Apply these techniques in your project to optimize performance and scalability. Each technique targets specific bottlenecks and enhances the efficiency of your React application.