FE202 Sprint Summary

Modified on Mon, 22 Jul at 5:22 PM

Usage Directions:

This is a comprehensive summary of the FE-202 Sprint. Revising the entire content is estimated to require 1 to 2 hours of effort. We recommend approaching this task in parts for a more effective revision process.

All the best!


TABLE OF CONTENTS


Creating Mock Server Using Postman


What is it?

A mock server in Postman allows you to simulate an API server, providing predefined responses to requests.


Where is it used?

It is used for testing APIs without needing a fully functional backend, ensuring frontend developers can proceed with integration.


How is it used?

1. Open Postman and create a new collection.

2. Add requests to the collection with predefined responses.

3. Use the "Mock Server" feature to create a mock server and link it to the collection.

4. Set the desired response for each request.


{

  "method": "GET",

  "url": "/api/users",

  "response": {

    "status": 200,

    "body": {

      "users": [{ "id": 1, "name": "John Doe" }]

    }

  }

}


Takeaways/Best Practices

- Use mock servers to develop and test the frontend independently from the backend.

- Ensure mock data closely resembles real data to avoid integration issues later.

- Regularly update mock responses as backend API evolves.


Parallel API calls using Promise Combinators


What is it?

Promise combinators are methods in JavaScript that handle multiple promises simultaneously.


Where is it used?

They are used in situations requiring parallel processing of asynchronous operations, such as making multiple API calls in a React app.


How is it used?

- `Promise.all()`: Waits for all promises to resolve.

- `Promise.allSettled()`: Waits for all promises to settle (resolve or reject).

- `Promise.race()`: Returns the first settled promise.

- `Promise.any()`: Returns the first fulfilled promise.


const fetchData1 = () => fetch('/api/data1').then(res => res.json());

const fetchData2 = () => fetch('/api/data2').then(res => res.json());



Promise.all([fetchData1(), fetchData2()])

  .then(([data1, data2]) => {

    console.log('Data 1:', data1);

    console.log('Data 2:', data2);

  })

  .catch(error => {

    console.error('Error fetching data:', error);

  });



Takeaways/Best Practices

- Use `Promise.all()` for independent operations that should be executed in parallel.

- Use `Promise.allSettled()` when you need to wait for all promises regardless of their outcome.

- Use `Promise.race()` to handle the first promise that settles.

- Use `Promise.any()` to handle the first promise that fulfills.


Debouncing


What is it?

Debouncing is a technique to limit the rate at which a function executes.


Where is it used?

It is used to optimize performance by reducing the frequency of function calls, such as in search input fields.


How is it used?


function debounce(func, delay) {

  let timeoutId;

  return function(...args) {

    clearTimeout(timeoutId);

    timeoutId = setTimeout(() => func.apply(this, args), delay);

  };

}



const handleInputChange = debounce((event) => {

  console.log('Input value:', event.target.value);

}, 300);



// Usage in a React component

function SearchInput() {

  return <input type="text" onChange={handleInputChange} />;

}


Takeaways/Best Practices

- Use debouncing to improve performance by limiting the rate of function execution.

- Choose an appropriate delay time based on user experience and performance needs.

- Ensure the debounced function preserves the correct `this` context and arguments.


Lifting State Up


What is it?

Lifting state up is a pattern in React where shared state is moved to the closest common ancestor of components that need it.


Where is it used?

It is used to ensure that multiple components have access to and can update the same state.


How is it used?

function Parent() {

  const [sharedState, setSharedState] = useState('');



  return (

    <>

      <Child1 state={sharedState} setState={setSharedState} />

      <Child2 state={sharedState} setState={setSharedState} />

    </>

  );

}



function Child1({ state, setState }) {

  return (

    <input

      type="text"

      value={state}

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

    />

  );

}



function Child2({ state }) {

  return <p>{state}</p>;

}



Takeaways/Best Practices

- Lift state up to the nearest common ancestor to share state between components.

- Avoid prop drilling by using context if state needs to be shared deeply in the component tree.

- Keep the state management logic centralized to make debugging and maintenance easier.


ReactJS Local Setup


What is it?

Setting up a local ReactJS environment for development.


Where is it used?

It is used to create, build, and run React applications locally.


How is it used?

1. Install Node.js and npm.

2. Create a new React app using `create-react-app`.

3. Run the app locally.


npx create-react-app my-app

cd my-app

npm start



Takeaways/Best Practices

- Ensure Node.js and npm are up-to-date to avoid compatibility issues.

- Use `create-react-app` for a quick and easy setup with all necessary configurations.

- Regularly update dependencies to benefit from security patches and new features.


Module-Scoped CSS


What is it?

CSS modules allow for locally scoped CSS by automatically generating unique class names.


Where is it used?

It is used to prevent CSS class name conflicts in React applications.


How is it used?

/* styles.module.css */

.header {

  color: blue;

}
import styles from './styles.module.css';



function Component() {

  return <h1 className={styles.header}>Hello World</h1>;

}


Takeaways/Best Practices

- Use CSS modules to avoid class name conflicts and keep styles scoped to components.

- Follow naming conventions for CSS classes to maintain readability and consistency.

- Use CSS-in-JS solutions like styled-components for dynamic styling needs.



Breaking a Figma Design into Atomic Components


What is it?

The process of breaking down a design from Figma into reusable, atomic components in React.


Where is it used?

It is used to create maintainable and reusable UI components.


How is it used?

1. Analyze the design and identify reusable components.

2. Create React components for each identified part.


// Atomic Component: Button

function Button({ label, onClick }) {

  return <button onClick={onClick}>{label}</button>;

}



// Composite Component: Header

function Header() {

  return (

    <header>

      <Button label="Home" onClick={() => alert('Home clicked')} />

      <Button label="About" onClick={() => alert('About clicked')} />

    </header>

  );

}



// Usage in a Page

function Page() {

  return (

    <div>

      <Header />

      <main>

        <h1>Welcome to the Page</h1>

      </main>

    </div>

  );

}


Takeaways/Best Practices

- Break down designs into the smallest reusable components (atoms).

- Use a consistent naming convention for components to improve readability and maintainability.

- Ensure components are modular and composable to facilitate reuse.



3rd Party UI Library Integration

Material UI Grid


What is it?

A responsive grid layout system in Material UI.


Where is it used?

It is used to create flexible and responsive layouts.


How is it used?

import { Grid } from '@material-ui/core';



function MyGrid() {

  return (

    <Grid container spacing={3}>

      <Grid item xs={12} sm={6}>

        <div>Item 1</div>

      </Grid>

      <Grid item xs={12} sm={6}>

        <div>Item 2</div>

      </Grid>

    </Grid>

  );

}


Takeaways/Best Practices

- Use Material UI Grid to create responsive layouts with minimal effort.

- Leverage the grid system to manage layout across different screen sizes.

- Combine the grid with other Material UI components for a cohesive design.


Material UI React Tabs Component


What is it?

A tab component from Material UI for organizing content.


Where is it used?

It is used to create tabbed navigation interfaces.


How is it used?

import { Tabs, Tab, Box } from '@material-ui/core';

import { useState } from 'react';



function MyTabs() {

  const [value, setValue] = useState(0);



  const handleChange = (event, newValue) => {

    setValue(newValue);

  };



  return (

    <Box>

      <Tabs value={value} onChange={handleChange}>

        <Tab label="Tab 1" />

        <Tab label="Tab 2" />

      </Tabs>

      {value === 0 && <Box>Content for Tab 1</Box>}

      {value === 1 && <Box>Content for Tab 2</Box>}

    </Box>

  );

}


Takeaways/Best Practices

- Use tabs to organize related content into distinct sections.

- Ensure tabs are accessible by providing keyboard navigation and appropriate ARIA attributes.

- Customize the appearance of tabs to match the design requirements.



What is it?

A carousel component with navigation support using SwiperJS.


Where is it used?

It is used to create interactive image or content sliders.


How is it used?

import { Swiper, SwiperSlide } from 'swiper/react';

import 'swiper/swiper-bundle.min.css';

import 'swiper/components/navigation/navigation.min.css';

import SwiperCore, { Navigation } from 'swiper/core';



SwiperCore.use([Navigation]);



function MyCarousel() {

  return (

    <Swiper navigation>

      <SwiperSlide>Slide 1</SwiperSlide>

      <SwiperSlide>Slide 2</SwiperSlide>

    </Swiper>

  );

}


Takeaways/Best Practices

- Use SwiperJS for a feature-rich and customizable carousel component.

- Optimize images and content in the slides for better performance.

- Customize navigation buttons and other elements to match the design requirements.


Advanced Hooks in ReactJS

useRef Hook


What is it?

A React hook that creates a mutable object to hold a reference to a DOM element or a value.


Where is it used?

It is used for accessing and interacting with DOM elements directly.


How is it used?

import { useRef, useEffect } from 'react';



function FocusInput() {

  const inputRef = useRef();



  useEffect(() => {

    inputRef.current.focus();

  }, []);



  return <input ref={inputRef} />;

}


Takeaways/Best Practices

- Use `useRef` to access DOM elements directly without triggering re-renders.

- Avoid using `useRef` for state management; use state hooks for reactive state.

- Use refs sparingly to keep the codebase clean and maintainable.


useMemo Hook


What is it?

A React hook that memoizes the result of a function to improve performance.


Where is it used?

It is used to avoid expensive calculations on every render.


How is it used?

import { useMemo } from 'react';



function ExpensiveCalculation({ num }) {

  const fibonacci = (n) => {

    if (n <= 1) return n;

    return fibonacci(n - 1) + fibonacci(n - 2);

  };



  const calculatedValue = useMemo(() => fibonacci(num), [num]);



  return <div>Fibonacci value: {calculatedValue}</div>;

}


Takeaways/Best Practices

- Use `useMemo` to memoize expensive computations and improve performance.

- Ensure the dependency array accurately reflects all dependencies of the memoized function.

- Avoid premature optimization; only use `useMemo` when performance issues are observed.



useCallback Hook


What is it?

A React hook that memoizes a callback function to prevent unnecessary re-renders.


Where is it used?

It is used to optimize performance when passing functions to child components.


How is it used?

import { useCallback } from 'react';



function Child({ onClick }) {

  return <button onClick={onClick}>Click me</button>;

}



function Parent() {

  const handleClick = useCallback(() => {

    console.log('Button clicked');

  }, []);



  return <Child onClick={handleClick} />;

}


Takeaways/Best Practices

- Use `useCallback` to memoize functions and prevent unnecessary re-renders of child components.

- Ensure the dependency array accurately reflects all dependencies of the callback function.

- Combine `useCallback` with `useMemo` for optimized performance in complex scenarios.


useContext Hook


What is it?

A React hook that allows for sharing state and functions globally in a React application.


Where is it used?

It is used to manage global state without prop drilling.


How is it used?

import { createContext, useContext, useState } from 'react';



const MyContext = createContext();



function MyProvider({ children }) {

  const [value, setValue] = useState('Hello World');

  

  return (

    <MyContext.Provider value={{ value, setValue }}>

      {children}

    </MyContext.Provider>

  );

}



function MyComponent() {

  const { value, setValue } = useContext(MyContext);

  

  return (

    <div>

      <p>{value}</p>

      <button onClick={() => setValue('New Value')}>Change Value</button>

    </div>

  );

}



// Usage in App

function App() {

  return (

    <MyProvider>

      <MyComponent />

    </MyProvider>

  );

}


Takeaways/Best Practices

- Use context to share state and functions across the component tree without prop drilling.

- Keep context usage to a minimum to avoid unnecessary re-renders.

- Combine context with other state management solutions (like Redux) for larger applications.



Custom Hook


What is it?

A custom hook is a reusable function that encapsulates logic using React hooks.


Where is it used?

It is used to abstract and reuse stateful logic across multiple components.


How is it used?

import { useState, useEffect } from 'react';



function useFetch(url) {

  const [data, setData] = useState(null);

  const [loading, setLoading] = useState(true);

  const [error, setError] = useState(null);



  useEffect(() => {

    fetch(url)

      .then((response) => response.json())

      .then((data) => {

        setData(data);

        setLoading(false);

      })

      .catch((error) => {

        setError(error);

        setLoading(false);

      });

  }, [url]);



  return { data, loading, error };

}



function DataFetchingComponent({ url }) {

  const { data, loading, error } = useFetch(url);



  if (loading) return <p>Loading...</p>;

  if (error) return <p>Error: {error.message}</p>;



  return (

    <div>

      <h1>Data</h1>

      <pre>{JSON.stringify(data, null, 2)}</pre>

    </div>

  );

}



// Usage in App

function App() {

  return <DataFetchingComponent url="https://api.example.com/data" />;

}


Takeaways/Best Practices

- Create custom hooks to encapsulate and reuse logic across multiple components.

- Ensure custom hooks follow the naming convention `useXyz` to denote their purpose.

- Test custom hooks thoroughly to ensure they handle different scenarios correctly.


Was this article helpful?

That’s Great!

Thank you for your feedback

Sorry! We couldn't be helpful

Thank you for your feedback

Let us know how can we improve this article!

Select at least one of the reasons
CAPTCHA verification is required.

Feedback sent

We appreciate your effort and will try to fix the article