Closed w3bdesign closed 2 weeks ago
Use TypeScript interfaces for better type safety:
interface Hero {
text: string;
}
interface HeroProps {
content: Hero[];
}
Utilize React.FC for functional components:
const Hero: React.FC<HeroProps> = ({ content }) => { ... }
Consider extracting the background image styles into a separate CSS file or use CSS modules for better separation of concerns.
Use optional chaining and nullish coalescing for safer access to content:
<h2>{content?.[0]?.text ?? "Hei!"}</h2>
Consider creating separate components for each section of the hero (e.g., HeroTitle, HeroSubtitle) to improve readability and maintainability.
Use React.memo to optimize performance for components that don't frequently update:
export default React.memo(Hero);
Move the AnimateIcons array outside the component to prevent unnecessary re-creation on each render:
const AnimateIcons: IAnimateIcons[] = [
{ id: 0, Icon: FaReact, iconName: "React" },
// ...
];
const Icons: React.FC = () => { ... }
Use React.memo to optimize performance:
export default React.memo(Icons);
Consider using a custom hook for icon data if it might be used elsewhere in the application.
Separate the PortableText components into their own file for better organization.
Use TypeScript interfaces for better type safety:
interface SectionProps {
text: IText[];
title: string;
id: string;
}
const Section: React.FC<SectionProps> = ({ text, title, id }) => { ... }
Consider using React.memo for the Section component if it's likely to be re-rendered frequently with the same props.
Use optional chaining when mapping over pageContent:
{pageContent?.map((page) => <Section key={page.id} {...page} />)}
Consider moving the Sanity query to a separate file or custom hook for better separation of concerns.
Use TypeScript interfaces for the pageContent structure:
interface PageContent {
id: string;
title: string;
hero: Hero[];
content: IContent[];
}
Add error handling for the Sanity fetch:
try {
const pageContent = await client.fetch(pageContentQuery);
// ...
} catch (error) {
console.error("Failed to fetch page content:", error);
// Handle error state
}
Consider using Suspense for a better loading experience:
import { Suspense } from 'react';
// ...
<Suspense fallback={<LoadingSpinner />}>
{pageContent.hero && <DynamicHero content={pageContent.hero} />}
</Suspense>
General Recommendations:
single-responsibility principle (SRP)
React Component Best Practices
When returning multiple elements from a component, use React Fragments instead of unnecessary divs:
Benefits:
Don't add layout styles (margin, flexbox, grid) to reusable components like buttons or headings.
Instead, use one of these approaches: a. Add a wrapper div with layout styles:
b. Use a className prop for flexibility:
Implement TypeScript to catch errors early and improve code quality:
Benefits:
By following these best practices, you can create more maintainable, flexible, and robust React components.
Optimizing React Component Structure and State Management
Preventing Prop Drilling
Using the Children Pattern
Instead of passing props through multiple layers of components, we can use the children pattern:
This approach:
Considerations
Proper State Updates
Using the Updater Function
When updating state based on its previous value, use the updater function:
Benefits:
Handling Multiple Actions on State Change
Instead of passing the setter function directly, create a custom function to handle multiple actions:
This approach:
By implementing these practices, you can create more maintainable and efficient React components while avoiding common pitfalls in state management and prop passing.
React Best Practices
1. Avoid Hardcoded Values
The Problem with Magic Numbers and Strings
When building React applications, it's crucial to avoid hardcoding values directly into components. This practice, often referred to as using "magic numbers" or "magic strings," can lead to maintenance issues and make your code less scalable.
Example: To-Do List Application
Consider a to-do list application where we want to limit free users to adding only three items. Initially, we might implement this directly in the component:
The Better Approach: Extracting Constants
Instead of hardcoding values, it's better to define constants:
Create a file, e.g.,
src/library/constants.js
:Then import and use in your component:
Benefits of Using Constants
By following this practice, you separate configuration from logic, making your React components more maintainable and your codebase more robust.
Improving React Data Fetching and Component Structure
Data Fetching with React Query
When fetching data in React, using
useEffect
for every request can lead to inefficient network calls. React Query offers a more optimized solution:useEffect
with React Query'suseQuery
hook.Example:
Best Practices for Data Fetching
Improving Component Structure
Breaking Down Large Components
Example:
Extracting Repeated Markup
Example:
Typing in TypeScript
Properly type your components and data structures:
By following these practices, you can create more maintainable, efficient, and readable React applications.
Best Practices for React Development
Using Constants and Variables
Benefits of Using Constants
Example: Sensitive Words Check
State Initialization
Using Constants for Initial State
Benefits of Defining Constants Outside Components
Folder Structure Best Practices
Key Principles
Recommended Structure
Notes on Folder Structure
Component Creation Best Practices
When to Create Components
Tips for Component Creation
By following these best practices, you can create more organized, maintainable, and efficient React applications. Remember that these guidelines are flexible and should be adapted to your specific project needs.
Here's an improved and structured version of the transcription:
Best Practices for State Management in React
Using Update Functions with useState
When updating state that depends on the previous state, it's best to use the update function approach:
This practice is recommended because:
Managing Complex State
Boolean States vs. Union Types
Instead of using multiple boolean states (e.g., isLoading, isError), consider using a single state with a union type:
Benefits:
Managing Selected Items in Lists
When dealing with lists where items can be selected:
Benefits:
State vs. URL Parameters
For certain types of data, especially those that should be shareable or bookmarkable, consider using URL parameters instead of state:
Example: Color selection on an e-commerce site
?color=white
)Benefits:
By following these practices, you can create more maintainable and robust React applications with cleaner state management.
Improving Component Structure and Reusability
When dealing with events that require multiple actions, it's best to create a handler function that encompasses all the necessary logic. This approach keeps components simpler and more focused.
Example:
Avoid passing raw setter functions or complex logic to lower-level components. Instead, create handler functions that encapsulate the required logic and pass these functions as props.
Keep state and its update functions close together in the component tree. This makes it easier to manage and understand how the state is being modified.
Example:
Follow conventions similar to native HTML or JSX events when naming props for custom components:
onAddTodo
,onClick
,onChange
handleAddTodo
,handleClick
Use TypeScript to define prop types, which helps catch errors and provides better documentation:
When creating reusable components like buttons, keep them generic and customizable through props:
Move specific logic and state management to higher-level components, keeping lower-level components simple and reusable.
By following these practices, you can create more maintainable, reusable, and understandable React components. This approach allows for better separation of concerns and makes it easier to reason about your application's structure and behavior.
React UI Component Best Practices
Identifying Reusable Components
When building a React application, it's crucial to identify opportunities for component reuse. This approach offers several benefits:
Example: Reusable Button Component
In our app, we have three buttons that share similar markup, styling, and functionality:
By creating a single, reusable button component, we can:
Creating Components for Organization
Even when components aren't reusable, it's often beneficial to create separate components for organizational purposes. Examples include:
These components improve code readability and make the overall structure of the app easier to understand.
Best Practices for Component Creation
Avoiding Unnecessary Divs
When creating components, it's common to see unnecessary wrapper divs. Best practices include:
Handling Conditional Rendering
When dealing with conditional rendering, such as showing different buttons based on user authentication status, consider these approaches:
By following these best practices, you can create more maintainable, efficient, and organized React applications.
Here's an improved and structured version of the text:
React Component Best Practices and Performance Optimization
Generalizing Components
When creating components, aim to make them more general and reusable:
onClick
for a click event)onAddTodo
)Performance Optimization with Hooks
useMemo
Use
useMemo
for expensive calculations or to prevent unnecessary re-computations:Benefits:
useCallback
Use
useCallback
for functions to prevent unnecessary recreations:Benefits:
React.memo
Wrap components with
React.memo
to prevent unnecessary re-renders:Use in conjunction with
useMemo
oruseCallback
for props to ensure maximum benefit.State Management Best Practices
When updating state that depends on previous state, use the updater function format:
Benefits:
Future Considerations
Remember, mastering these concepts takes practice. Consider diving deeper into React courses or documentation for a more comprehensive understanding.
Improving React Component Structure and Reusability
To improve code readability and maintainability, create smaller, more specific components for repetitive or complex elements. For example:
For complex JavaScript logic, create utility functions to improve readability and reusability:
To avoid duplicating markup for similar elements:
For complex logic within components:
For reusable logic that includes React hooks:
Follow these guidelines for creating reusable code:
When using local storage with useState:
By applying these best practices, you can significantly improve the structure, readability, and reusability of your React components. Remember to handle TypeScript issues and refer to comprehensive courses for more in-depth coverage of these topics.
Improving React Component Design with TypeScript
TypeScript can significantly enhance your React development experience by providing type checking and intelligent code completion. Here's how to use TypeScript effectively with React props:
Define prop types explicitly:
Use the defined types in your component:
Benefits of using TypeScript:
A best practice in React is to keep components, especially reusable ones, as simple or "dumb" as possible. This improves reusability and maintainability.
Example: Status Bar Component
Instead of:
Prefer:
Benefits:
Calculate derived state close to where the original state is managed, rather than in child components.
Example:
Instead of passing state setters down through multiple levels of components, consider using context or state management libraries for complex state scenarios.
Example of what to avoid:
Better approach: Use React Context or state management libraries like Redux for managing global state and actions.
By following these best practices, you can create more maintainable, reusable, and scalable React applications.
Here's an improved and structured version of the transcription:
URL-based State Management in React
Benefits of URL-based State
Implementation Example
https://example.com/product?color=black&size=medium
Best Practices
Understanding and Using the useEffect Hook
Basic Concept
Common Use Cases
Example: Synchronizing with localStorage
Best Practices
Incorrect Example:
Correct Example:
Data Fetching with useEffect
Example Implementation
Considerations
By structuring the content and improving readability, the key points of the transcription are now more clearly presented and easier to understand.