diff --git a/documentation/blog/2022-12-21-em-vs-rem.md b/documentation/blog/2024-07-19-em-vs-rem.md similarity index 56% rename from documentation/blog/2022-12-21-em-vs-rem.md rename to documentation/blog/2024-07-19-em-vs-rem.md index 2e49b44e39d2..3e800bee6b41 100644 --- a/documentation/blog/2022-12-21-em-vs-rem.md +++ b/documentation/blog/2024-07-19-em-vs-rem.md @@ -4,10 +4,12 @@ description: We'll look at everything em and rem, their differences, when and ho slug: rem-vs-em authors: fimber_elemuwa tags: [css] -image: https://refine.ams3.cdn.digitaloceanspaces.com/blog/2022-12-21-em-vs-rem/social.png +image: https://refine.ams3.cdn.digitaloceanspaces.com/blog/2022-12-21-em-vs-rem/social-2.png hide_table_of_contents: false --- +**This article was last updated on July 19, 2024, to add sections for Accessibility Considerations, Advanced Usage of em and rem, and Performance Implications.** + ## Introduction CSS is a crucial part of any website’s design, but understanding the nuances of how to use it can be tricky. One of the most important things to understand is the difference between using rem and em in CSS and why/when you should be using either. @@ -18,7 +20,6 @@ In this article, we'll look at everything em and rem, their differences, when an Steps we'll cover in this article: -- [Prerequisites](#prerequisites) - [em and rem units in CSS](#em-and-rem-units-in-css) - [What is CSS em](#what-is-css-em) - [What is CSS rem](#what-is-css-rem) @@ -155,7 +156,93 @@ As you can see, despite the child-2 div being inside another divs, it goes back Using the "rem" unit allows for a more scalable and flexible way to size elements on a page because if you change the font-size of the root element, all elements sized with the "rem" unit will be updated automatically to maintain their relative size. -Here’s a codepen link if you’d like to play with the above code a bit. +## Advanced Usage of em and rem + +I thought it would be useful to dive deeper into some advanced techniques for using em and rem units in our CSS. These units offer a lot of flexibility, and we can leverage them to create more dynamic and responsive designs. + +Here are a few advanced strategies for using em and rem units: + +### Compound Scaling with em + +We can use em units to create compound scaling effects within nested elements. For instance, if we set a parent element to have a font size of 2em, and a child element to have a font size of 1.5em, the child’s font size will be 1.5 times the parent’s size, creating a scalable hierarchy. + +```css +.parent { + font-size: 2em; +} + +.child { + font-size: 1.5em; /* This will be 1.5 * 2em = 3em */ +} +``` + +### Responsive Typography with rem + +Using rem units for typography ensures that all text scales relative to the root font size. By adjusting the root font size with media queries, we can easily create responsive typography. + +```css +html { + font-size: 16px; /* Default root font size */ +} + +@media (max-width: 600px) { + html { + font-size: 14px; /* Smaller font size for small screens */ + } +} + +body { + font-size: 1rem; /* 1rem = 16px by default, 14px on small screens */ +} +``` + +### Padding and Margins with rem + +We can use rem units for padding and margins to maintain consistent spacing across different screen sizes. This approach ensures that spacing scales appropriately when the root font size changes. + +```css +.container { + padding: 2rem; /* Padding will scale with the root font size */ + margin: 1rem auto; +} +``` + +### Combining em and rem + +In some cases, combining em and rem can offer the best of both worlds. For example, we can use rem units for global settings and em units for local, relative adjustments within components. + +```css +.global { + font-size: 1rem; /* Relative to root */ +} + +.component { + font-size: 1.5em; /* Relative to its parent, .global in this case */ +} +``` + +### Creating Modular Scales +We can use em or rem units to create modular scales, which are predefined ratios for scaling text and other elements. This method provides a consistent visual rhythm across the site. + +```css +html { + font-size: 16px; /* Base font size */ +} + +.h1 { + font-size: 3rem; /* 48px */ +} + +.h2 { + font-size: 2.25rem; /* 36px */ +} + +.h3 { + font-size: 1.5rem; /* 24px */ +} +``` + +By using these advanced techniques, we can create more adaptable and visually consistent designs. ## Differences between em and rem units @@ -177,6 +264,77 @@ em and rem are by far the best units to use today when specifying length, but li Overall, while em and rem units can be helpful in certain situations, it's important to consider their potential drawbacks carefully and whether they are the best choice for your project. +## Accessibility Considerations + +Let me share some thoughts on the ways in which we could make our web designs much more accessible using em and rem units in CSS. Things that really make a difference, for instance, are how the content would be perceived or accessed by a user with disabilities. + +You can increase the accessibility of our web pages using em and rem units. Here's why: + +### Scalable Font Sizes + +Because I used either `em` or `rem` for the font sizes, then text on the webpage gets scalable to respond to user needs. This is beneficial to people with visual impairments who may desire a larger text size for comfort in reading. Browsers can scale these units more easily than fixed units. + +### Consistent Spacing + +By using rem for margins, padding, and other spacing properties, it's certain everything scales consistently. This could improve the predictability of the layout structure, which can help users with cognitive disabilities. + +### Responsive Design + +As already explained, both 'em' and 'rem' units are relative units, so designing a responsible layout becomes a lot easier. The layout then dynamically adapts according to screen size because the sizes of screens change, which is paramount as users are from diverse devices and can use assistive technologies. + +### User Preferences + +Some users set up their browser to have a different font size from the default to increase readability. By designing with `rem` units, user styles get respected, and our content stays accessible. + +### Reduced Motion and Distraction + +Em and rem units make it more in control to resize and reposition the elements, reducing unnecessary movement and distractions visually—a very challenging experience for users with attention-related disabilities. In short, we use em and rem units in our CSS to make the design more accessible and user-friendly. It is such a small but powerful way of using inclusive and adaptive design to cater to a wider scope of user needs. + +## Implications on Performance + +I just want to share with you some insights on what impacts performance when using em or rem units within CSS. Understanding them can serve to make better decisions for the design of our stylesheets to ensure the applications run smoothly. + +### Reflow and Repaint + +When we use em units, the browser needs to calculate sizes relative to their parent elements. That can lead to reflows and repaints when structures are deeply nested. This is one reason using rem units can make for less complexity; in this case, all calculations are only relative to the root element. + +### Maintaining Consistency + +The application will use rem units consistently. This is really helpful for responsive design. Changing the root font size will scale all other elements that use rem units in a proportional manner. It could lead to an easier rendering process within the browser. + +### Memory Usage + +Em units might mean more memory usage: Since each element with an em unit needs to remember the computed value based on its parent, rem units based on the root may keep memory usage small and predictable. + +### CSS Calculations + +The browser computes the size and position of elements used by CSS calculations. This makes em units slightly heavy computationally, as they have to reference parents in any given case. Rem units in some calculations have only one reference point; therefore, it can be much simpler, making it computationally faster. + +### Layout Stability + +Units in rem can maintain layout stability between multiple screen sizes and resolutions. Because the base font size inside the root element is set, and the unit for element sizes is rem, all other elements will be resized proportionally; as a result, layout shifting will be lesser, and user experience will increase. + +### Readability and Maintenance + +Using rem units will allow you to have more readability and maintainability in your stylesheet. Defining this base value globally makes the size of elements at a glance predictable and visible in your stylesheets. This could cut down on hours spent debugging layout concerns and actually make development a whole lot more productive. + +For example, let's consider this quick example to draw out the points above: + +```css +html { + font-size: 16px; /* Base font size */ +} + +.container { + padding: 2rem; /* Easier for the browser to calculate */ + margin: 1rem auto; +} + +.child { + font-size: 1.5em; /* Less work for the browser to calculate */ +} +``` + ## Conclusion If you made it here, congratulations! You now know all there is to know about em and rem and why we need them. Though they’re both similar, they’re distinctly different and should be treated accordingly. diff --git a/documentation/blog/2023-01-03-use-swr.md b/documentation/blog/2024-07-19-use-swr.md similarity index 72% rename from documentation/blog/2023-01-03-use-swr.md rename to documentation/blog/2024-07-19-use-swr.md index 5062ff92f80f..f31f6a176ed5 100644 --- a/documentation/blog/2023-01-03-use-swr.md +++ b/documentation/blog/2024-07-19-use-swr.md @@ -4,10 +4,12 @@ description: Introduction to SWR and useSwr for Client-Side Data Fetching slug: data-fetching-next-js-useswr authors: michael tags: [nextjs] -image: https://refine.ams3.cdn.digitaloceanspaces.com/blog/2023-01-03-use-swr/social.png +image: https://refine.ams3.cdn.digitaloceanspaces.com/blog/2023-01-03-use-swr/social-2.png hide_table_of_contents: false --- +**This article was last updated on July 19, 2024, to add sections for Error Handling, Mutations and Caching Strategies with SWR.** + ## Introduction Data is unquestionably an important component of any modern web application today. And, as the web evolves and innovates, new methods of interacting with this data must emerge in order to provide users with a better experience when interacting with our applications. @@ -18,18 +20,6 @@ SWR is one of the most powerful client-side data fetching libraries for frontend Whether you are new to React.js or an experienced developer looking to optimize your data fetching strategy, SWR is a powerful tool worth considering! Now, let's get started! -Steps we'll cover: - -- [What is SWR and useSWR?](#what-is-swr-and-useswr) -- [Setting up an Example App With SWR](#setting-up-an-example-app-with-swr) -- [Additional Features of SWR](#additional-features-of-swr) - -## Prerequisites - -To follow along well with this tutorial, it's essential that you have basic knowledge of JavaScript and React. SWR is a library for use with React and its frameworks, so it's required that you're familiar with the basics of both of these technologies. - -In addition, make sure you have [Node](https://nodejs.org/) installed on your computer before continuing. - ## What is SWR and `useSWR`? SWR is an acronym for stale-while-revalidate. It's a lightweight React.js library with hooks for data fetching on the client-side. SWR is bootstrapped with various hooks that are used for various performance improvement techniques such as data caching, re-validation, pagination, and many others. @@ -480,12 +470,126 @@ export default function App() { } ``` -
-
- - discord banner - -
+## Mutations with SWR + +I wanted to share some details about handling mutations with SWR to help us efficiently manage data updates in our React applications. Here are some practical tips and examples: + +SWR provides an excellent way to mutate data, which means updating or changing the cached data. This is useful for operations like creating, updating, or deleting records. Using the `mutate` function, we can optimistically update the UI and revalidate the data in the background. + +Here’s a simple example of how to use `mutate` with SWR: + +```javascript +import useSWR, { mutate } from "swr"; + +const fetcher = (url) => fetch(url).then((res) => res.json()); + +const MyComponent = () => { + const { data, error } = useSWR("/api/data", fetcher); + + const handleUpdate = async () => { + // Optimistically update the data + mutate("/api/data", newData, false); + + // Send the update request to the server + await fetch("/api/data", { + method: "POST", + body: JSON.stringify(newData), + }); + + // Revalidate the data + mutate("/api/data"); + }; + + if (error) return
Failed to load data. Please try again later.
; + if (!data) return
Loading...
; + + return ( +
+ {data.map((item) => ( +
{item.name}
+ ))} + +
+ ); +}; + +export default MyComponent; +``` + +In this example, we optimistically update the cached data before sending the update request to the server. After the server request completes, we revalidate the data to ensure it is up-to-date. + +### Handling Mutations + +**Optimistic UI Updates**: SWR allows you to update the UI optimistically, which means reflecting the changes immediately without waiting for the server response. This provides a better user experience. + +```javascript +mutate("/api/data", newData, false); // Optimistically update data +``` + +**Revalidation**: After performing the mutation, you should revalidate the data to ensure consistency. + +```javascript +mutate("/api/data"); // Revalidate data +``` + +**Error Handling**: Handle errors gracefully to ensure the UI doesn’t break when there are issues with the mutation. + +```javascript +const handleUpdate = async () => { + try { + mutate("/api/data", newData, false); + await fetch("/api/data", { + method: "POST", + body: JSON.stringify(newData), + }); + mutate("/api/data"); + } catch (error) { + console.error("Failed to update data:", error); + } +}; +``` + +## Error Handling with SWR + +I wanted to share some insights on handling errors gracefully when using SWR for data fetching in our React projects. Here are some strategies and examples that might help: + +When using the `useSWR` hook, handling errors is straightforward. The hook returns an `error` object that we can use to display error messages or fallback content to the user. + +Here's a simple example: + +```javascript +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
Failed to load data. Please try again later.
; + if (!data) return
Loading...
; + + return ( +
+ {/* Render your data here */} + {data.map((item) => ( +
{item.name}
+ ))} +
+ ); +}; + +export default MyComponent; +``` + +In this example, the component first checks if there's an error. If an error is detected, it displays a friendly error message. If there's no error but the data is still being fetched, it shows a loading indicator. Once the data is successfully fetched, it renders the data. + +### Tips for Handling Errors + +**Show User-Friendly Messages**: Always provide a clear and concise error message that guides the user on what went wrong and possible actions they can take. +**Use a Fallback UI**: In case of errors, provide a fallback UI so that the application doesn't break. This can be a simple message or a more sophisticated error boundary. +**Log Errors for Debugging**: Use logging tools to capture errors for debugging purposes. This helps in understanding and fixing issues faster. + +Implementing these strategies can make our applications more robust and improve the user experience. ### SWRDevTools @@ -516,6 +620,75 @@ You can read more about using TypeScript with SWR [here](https://swr.vercel.app/ This section only touched on a few of SWR's many capabilities, so your first encounter with it will not be overwhelming. You can however, check the [documentation](https://swr.vercel.app/docs/getting-started) for other features that might interest you. +## Caching Strategies with SWR + +I wanted to share some insights on caching strategies with SWR to improve the performance and user experience of our React applications. Here are some practical tips and examples that might help: + +SWR automatically caches data to optimize performance and reduce the number of network requests. However, there are several ways to customize caching to suit specific needs. + +Here's an example of basic caching with SWR: + +```javascript +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
Failed to load data. Please try again later.
; + if (!data) return
Loading...
; + + return ( +
+ {data.map((item) => ( +
{item.name}
+ ))} +
+ ); +}; + +export default MyComponent; +``` + +In this example, SWR automatically caches the data fetched from the API. + +### Custom Caching Strategies + +**Cache Time Control**: You can set a specific cache time for your data. This is useful if the data doesn't change frequently. + +```javascript +const { data, error } = useSWR("/api/data", fetcher, { + refreshInterval: 60000, +}); // Refresh every 60 seconds +``` + +**Revalidation**: SWR can revalidate the cache when the user focuses on the window or when network status changes. This ensures users always see the most up-to-date data. + +```javascript +const { data, error } = useSWR("/api/data", fetcher, { + revalidateOnFocus: true, + revalidateOnReconnect: true, +}); +``` + +**Manual Cache Management**: Sometimes, you may want to manually manage the cache, especially when dealing with real-time data updates or invalidations. + +```javascript +import useSWR, { mutate } from "swr"; + +// Manually mutate the cache +mutate("/api/data", newData, false); // Update the cache without revalidation +``` + +### Tips for Effective Caching + +**Set Reasonable Cache Intervals**: Depending on how frequently your data changes, set appropriate cache refresh intervals. +**Use Conditional Fetching**: Fetch data conditionally based on certain criteria to avoid unnecessary requests. +**Combine with Other State Management Libraries**: SWR can be combined with other state management libraries like Redux or Zustand for more complex scenarios. + +By implementing these caching strategies, we can ensure our applications are more efficient and provide a smoother experience for users. + ## Conclusion In this article, we learned about the basics of SWR, its importance in developing modern web applications, and how you can get started with it. We also created an example application in React and explored some capabilities of SWR to see its use cases and benefits over other conventional client-side data fetching methods. diff --git a/documentation/blog/2023-05-03-react-date-picker.md b/documentation/blog/2024-07-22-react-date-picker.md similarity index 61% rename from documentation/blog/2023-05-03-react-date-picker.md rename to documentation/blog/2024-07-22-react-date-picker.md index af558c03f8e1..2424abbab134 100644 --- a/documentation/blog/2023-05-03-react-date-picker.md +++ b/documentation/blog/2024-07-22-react-date-picker.md @@ -4,10 +4,12 @@ description: We’ll show you how to implement a date picker using the ‘react- slug: react-date-picker authors: irakli_tchigladze tags: [react] -image: https://refine.ams3.cdn.digitaloceanspaces.com/blog/2023-05-03-react-date-picker/social.png +image: https://refine.ams3.cdn.digitaloceanspaces.com/blog/2023-05-03-react-date-picker/social-2.png hide_table_of_contents: false --- +**This article was last updated on July 22, 2024, to add sections for Accessibility Considerations, Internationalization and Localization, and Performance Optimization.** + ## Introduction Having a date picker that is simple, intuitive and consistent may be necessary to ensure users have a good experience using your web application. @@ -506,12 +508,300 @@ By default, a date picker shows a calendar where users can select a date. Use th
-
-
- - discord banner - -
+## Accessibility Considerations + +I just wanted to share a few thoughts on how to make our date picker implementation accessible for all users. Accessibility is key, and here are a few key things we should bear in mind: + +### Keyboard Navigation + +- Ensure that the date picker is browsable and selectable using a keyboard, which in turn shall include browsing of dates by arrow keys, selection of date by pressing Enter, and closing the date picker by pressing Esc. +- Proper focus management should be ensured so that the date picker is an active element when open and on closing, the focus should get back to the element which triggers it. + +### ARIA Attributes + +- Use ARIA attributes like `aria-label` for buttons, `role="dialog"` on the date picker container, and `aria-live` on content that is dynamically updated. +- Ensure each date cell contains an `aria-label` that describes the date, for example, "July 17, 2024". + +### Screen Reader Support + +- Make sure the date picker is correctly announced by screen readers, with proper instruction and feedback on interaction. +- Tested with popular screen readers like JAWS, NVDA, and VoiceOver. + +### High Contrast Mode + +- Ensure that the date picker can be seen and used properly when in high contrast mode. This is especially of value to a visually impaired user. +- Test with Windows High Contrast mode and its counterparts in other operating systems. + +### Color Contrast + +- Ensure the presence of enough color contrast between elements such as text and interactive components. Contrast ratio should meet WCAG guidelines, while at the minimum, normal text should have a 4.5:1 contrast ratio. +- Make use of tools such as the Chrome DevTools Accessibility Pane or contrast checkers to verify online. + +### Responsive Design + +- Ensure that the date picker is usable on every screen size, from the smallest mobile screen to a large tablet. Tap-target sizes and hit areas need to be decently sized. +- Test on multiple devices and orientations for an acceptable experience. + +### Clear Instructions + +- Offer clear error messages and instructions. If a user has made an invalid selection, such as choosing an invalid date, explain to them the reason it's invalid and how to correct the mistake. +- It may guide users with inline instructions or tooltips about how to select a date. + +With these accessibility features, we can be sure that the date picker accommodates each and every one, regardless of their abilities. So let's go over these points once again, and then let's implement them in our date picker component and test thoroughly. + +## Internationalization and Localization + +There are some key issues in the area of Internationalization (i18n) and Localization (l10n) that I would like to raise as they relate to our date picker implementation. For the date picker, let's customize it for different languages and regions so users all over the world can share a common experience. + +### Language Support + +- Be able to translate the date picker to other languages. Use libraries or frameworks that support i18n, such as `react-i18next` or `react-intl`. +- All static text, such as names of the months, names of days, and any textual instructions, should be translatable. + +### Date Formats + +- Date format depends on locale, e.g., MM/DD/YYYY in the United States, DD/MM/YYYY in Europe. Datepicker should locale user's machine settings. +- Use a locale-aware library like `date-fns` or `moment.js` for date formatting and parsing. + +### Number Formats + +- Ensure that numeric values like years are formatted with respect to the locale being used while considering different systems of numerals. + +### Right-to-Left (RTL) Support + +- Some of the languages that read RTL are Arabic and Hebrew. There should be RTL layout support for date pickers so that a natural user reading and interacting experience can be maintained. +- Test the date picker within an RTL layout for elements alignment and usability. + +### Locale-Specific Holidays and Weekends + +- In other cultures, weekends might not take place on Saturday and Sunday. For instance, in some Middle Eastern countries, the weekend takes place on Friday and Saturday. +- Shows local holidays and weekends as per the user's locale. + +### Time Zone Awareness + +- If the date picker includes time entry, make sure that it properly supports time zones. Users should see the local time in their time zone. +- Make use of libraries such as `moment-timezone` for time zone conversions. + +### Cultural Sensitivities + +- Be mindful of cultural differences and sensitivities. Some colors, icons, and symbols have different connotations depending on the culture and the people. +- Ensure that the user interface of the date picker does not face any of these differences. + +### Testing + +- Test the date picker for different languages, date formats, and cultural settings. Use tools such as BrowserStack for testing on various locales and devices. +- Involve native speakers in the testing process, so that any translation error or cultural issue can be caught. + +Implementation of these best i18n and l10n practices on the date picker takes it one step further as we keep enhancing our component. + +## Performance Optimization + +I also wanted to touch on some critical aspects of optimization in performance that we should consider for our date picker, taking care that it runs in the most efficient manner and responds properly to user input. This would greatly improve the user experience—most importantly, for users with low-end devices or slow connections. + +### Lazy Loading + +- Load the components and data only when needed, like the date picker component should be loaded when only the user interacts with the input field. +- Use React's `React.lazy` with a `Suspense` wrapper to get component-level code-splitting. + +```tsx +import React, { Suspense, lazy } from "react"; + +const DatePicker = lazy(() => import("./DatePicker")); + +function App() { + return ( +
+ Loading...
}> + + + + ); +} + +export default App; +``` + +### Avoid Minimize Re-renders + +- Guarantee minimal re-rendering in the date picker component. The `React.memo` implementation takes care of this. +- Avoid passing a new object or function reference as a prop, it is better to avoid it because it will make re-renders. + +```tsx +import React, { useState, memo } from "react"; + +const DatePicker = memo(({ selectedDate, onDateChange }) => { + return ; +}); + +function App() { + const [date, setDate] = useState(new Date().toISOString().substr(0, 10)); + + const handleDateChange = (e) => { + setDate(e.target.value); + }; + + return ( +
+ +
+ ); +} + +export default App; +``` + +### Efficient State Management + +- Keep the state as minimal as possible. Store only values that are required to support the functionality of the date picker. +- Use the `useCallback` and `useMemo` hooks to memoize functions and values for preventing unnecessary calculations. + +```tsx +import React, { useState, useCallback, useMemo } from "react"; + +function DatePicker({ selectedDate, onDateChange }) { + return ; +} + +function App() { + const [date, setDate] = useState(new Date().toISOString().substr(0, 10)); + + const handleDateChange = useCallback((e) => { + setDate(e.target.value); + }, []); + + const formattedDate = useMemo(() => { + return new Date(date).toLocaleDateString(); + }, [date]); + + return ( +
+ +

Selected Date: {formattedDate}

+
+ ); +} + +export default App; +``` + +### Virtualization + +- If the date picker is rich in numbers of items, for example, years or months, use virtualization of visible items. The huge positive impact can be realized in reducing the loading time and scrolling performance at the start. +- Leverage libraries like `react-window` or `react-virtualized` for virtualization. + +```tsx +import React from "react"; +import { FixedSizeList as List } from "react-window"; + +const items = Array.from({ length: 1000 }, (_, index) => `Item ${index + 1}`); + +function DatePicker() { + return ( + + {({ index, style }) =>
{items[index]}
} +
+ ); +} + +export default DatePicker; +``` + +### Debouncing + +- For user input that triggers heavy computation or API calls (e.g., searching for dates or input validation), you'll want to debounce so the operations don't get called too frequently. +- Implement a debounce function that triggers the search after a predefined period of time in which a user has stopped typing. + +```tsx +import React, { useState } from "react"; +import { debounce } from "lodash"; + +function DatePicker() { + const [date, setDate] = useState(""); + const [searchTerm, setSearchTerm] = useState(""); + + const handleDateChange = (e) => { + setDate(e.target.value); + debouncedSearch(e.target.value); + }; + + const debouncedSearch = debounce((term) => { + // Simulate an API call + console.log("Searching for:", term); + }, 300); + + return ( +
+ + setSearchTerm(e.target.value)} + /> +
+ ); +} + +export default DatePicker; +``` + +### Code Splitting + +- Code split into small bundles to ensure the load time for the first instance. Use in-built support in React for code-splitting with React.lazy and dynamic imports. +- Analyze the bundle size with tools like Webpack Bundle Analyzer and optimize the build configuration based on the analysis. + +```tsx +import React, { Suspense, lazy } from "react"; + +const DatePicker = lazy(() => import("./DatePicker")); + +function App() { + return ( +
+ Loading...
}> + + + + ); +} + +export default App; +``` + +### Optimized Event Handling + +- Do not add many event listeners; it is expensive in terms of performance. Use event delegation when possible. +- Batch state updates and handle multiple events within one handler in order to cut on re-renders. + +```tsx +import React, { useState, useEffect } from "react"; + +function DatePicker() { + const [date, setDate] = useState(new Date().toISOString().substr(0, 10)); + + useEffect(() => { + const handleResize = () => { + console.log("Window resized"); + }; + + window.addEventListener("resize", handleResize); + return () => { + window.removeEventListener("resize", handleResize); + }; + }, []); + + const handleDateChange = (e) => { + setDate(e.target.value); + }; + + return ( +
+ +
+ ); +} + +export default DatePicker; +``` ## Conclusion diff --git a/documentation/blog/2023-01-30-compare-form-libraries.md b/documentation/blog/2024-07-23-compare-form-libraries.md similarity index 61% rename from documentation/blog/2023-01-30-compare-form-libraries.md rename to documentation/blog/2024-07-23-compare-form-libraries.md index bc015dc7f05f..76af44375f5a 100644 --- a/documentation/blog/2023-01-30-compare-form-libraries.md +++ b/documentation/blog/2024-07-23-compare-form-libraries.md @@ -4,10 +4,12 @@ description: This article will compare React Hook Form and Formik by highlightin slug: react-hook-form-vs-formik authors: joseph_mawa tags: [react-hook-form, comparison] -image: https://refine.ams3.cdn.digitaloceanspaces.com/blog/2023-01-30-compare-form-libraries/social.png +image: https://refine.ams3.cdn.digitaloceanspaces.com/blog/2023-01-30-compare-form-libraries/social-2.png hide_table_of_contents: false --- +**This article was last updated on July 23, 2024, to add sections for Custom Validation and Accessibility Features.** + ## Introduction Forms are a handy feature for collecting data from users. Unfortunately, creating, styling, and validating forms is not always straightforward, especially when using front-end frameworks such as React. Fortunately, packages such as [React Hook Form](https://react-hook-form.com/) and [Formik](https://formik.org/) exist to simplify working with forms in React and React frameworks. @@ -192,12 +194,227 @@ The above code illustrates a simple use case of the Formik library. It has sever | Open GitHub issues | 635 | 3 | | Closed GitHub issues | 1497 | 3528 | -
-
- - discord banner - -
+## Custom Validation with React Hook Form + +This would be a post to share some insights on how to apply custom validation in React forms using React Hook Form and Formik. I hope this simple guide will help all of us in our next project. + +Custom validation is pretty easy using React Hook Form. We'll set up our validation rules using the register function directly on input fields. Here's an example: + +```javascript +import { useForm } from "react-hook-form"; + +function MyForm() { + const { + register, + handleSubmit, + formState: { errors }, + } = useForm(); + + const onSubmit = (data) => { + console.log(data); + }; + + return ( +
+ + value.length >= 4 || "Username must be at least 4 characters", + })} + /> + {errors.username &&

{errors.username.message}

} + + + {errors.email &&

{errors.email.message}

} + + +
+ ); +} +``` + +In the above example, we put in place some custom validation messages for the username and email fields. + +## Custom Validation with Formik + +Formik also allows custom validation through its `validate` prop. We can write our validation logic inside a function and pass it to Formik. Here's an example: + +```javascript +import { Formik, Form, Field, ErrorMessage } from "formik"; + +function MyForm() { + return ( + { + const errors = {}; + if (!values.username) { + errors.username = "Username is required"; + } else if (values.username.length < 4) { + errors.username = "Username must be at least 4 characters"; + } + if (!values.email) { + errors.email = "Email is required"; + } else if ( + !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email) + ) { + errors.email = "Invalid email address"; + } + return errors; + }} + onSubmit={(values) => { + console.log(values); + }} + > + {({ handleSubmit }) => ( +
+ + + + + + + + + )} +
+ ); +} +``` + +In this case, we implemented custom validation for the `username` and `email` fields using a `validate` function. + +## Implementing Accessibility Features in React Forms + +I would like to share a few tips on how to implement the necessary accessibility features in our React forms with the help of React Hook Form and Formik. Accessibility is so important because it ensures our applications are accessible to everyone, including people with disabilities. Below are some guidelines with examples on how to enhance the accessibility of our forms. + +### Accessibility with React Hook Form + +With React Hook Form, form accessibility is just as easy. We should use semantic HTML elements and ARIA attributes where necessary. Here's an example: + +```tsx +import { useForm } from "react-hook-form"; + +function AccessibleForm() { + const { + register, + handleSubmit, + formState: { errors }, + } = useForm(); + + const onSubmit = (data) => { + console.log(data); + }; + + return ( +
+
+ + + {errors.username && {errors.username.message}} +
+ +
+ + + {errors.email && {errors.email.message}} +
+ + +
+ ); +} +``` + +In this example, we have used `aria-invalid` to indicate invalid fields and `role="alert"` to announce error messages to screen readers. + +### Accessibility with Formik + +Formik also supports accessibility enhancements. We should go ahead to support the same by the right use of semantic HTML elements and ARIA attributes. Here is an example: + +```tsx +import { Formik, Form, Field, ErrorMessage } from "formik"; + +function AccessibleForm() { + return ( + { + const errors = {}; + if (!values.username) { + errors.username = "Username is required"; + } + if (!values.email) { + errors.email = "Email is required"; + } else if ( + !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email) + ) { + errors.email = "Invalid email address"; + } + return errors; + }} + onSubmit={(values) => { + console.log(values); + }} + > + {({ handleSubmit, errors, touched }) => ( +
+
+ + + +
+ +
+ + + +
+ + +
+ )} +
+ ); +} +``` + +In this example, we ensured all the form fields have proper labels and ARIA attributes so they can be more accessible. Implementing these accessibility features will make our forms more user-friendly. ## Conclusion diff --git a/documentation/blog/2023-03-17-react-dashboard-libraries.md b/documentation/blog/2024-07-23-react-dashboard-libraries.md similarity index 81% rename from documentation/blog/2023-03-17-react-dashboard-libraries.md rename to documentation/blog/2024-07-23-react-dashboard-libraries.md index 57ae4917f260..1c6997c934e9 100644 --- a/documentation/blog/2023-03-17-react-dashboard-libraries.md +++ b/documentation/blog/2024-07-23-react-dashboard-libraries.md @@ -4,10 +4,12 @@ description: We have curated a compilation of the 5 best React admin dashboard l slug: react-admin-dashboard authors: david_omotayo tags: [comparison] -image: https://refine.ams3.cdn.digitaloceanspaces.com/blog%2F2023-03-17-react-dashboard-libraries%2Fsocial.png +image: https://refine.ams3.cdn.digitaloceanspaces.com/blog/2023-03-17-react-dashboard-libraries/social-2.png hide_table_of_contents: false --- +**This article was last updated on July 23, 2024, to add sections for use cases section.** + ## Introduction Admin dashboards play a crucial role in the success of B2B businesses. These dashboards are designed to provide a personalized overview of key performance indicators, data accuracy, and administrative actions, all of which have a significant impact on the decision-making process of a business administration, either positively or negatively. @@ -63,7 +65,7 @@ npm create refine-app@latest ### Stats -- GitHub stars: +16K +- GitHub stars: +27K - License: MIT - Links: [Demo](https://example.crm.refine.dev/) | [Documentation](https://refine.dev/tutorial) | [GitHub](https://github.com/refinedev/refine/tree/master/examples/app-crm) @@ -212,12 +214,39 @@ npm run start - License: MIT - Links: [Demo](https://demo.themesberg.com/volt-react-dashboard/#/dashboard/overview) | [Documentation](https://demo.themesberg.com/volt-react-dashboard/#/) | [GitHub](https://github.com/themesberg/volt-react-dashboard) -
-
- - discord banner - -
+## Use Cases + +I would like to point out a few use cases and real-world implementations where React admin dashboard libraries really shine. These are selected examples showing the application of these libraries in building powerful, effective, and user-friendly applications across industries. + +### E-Commerce Management + +- **Inventory Management:** Track and manage inventory levels, set reorder points, and monitor stock movements. +- **Order Processing:** View, update and manage the orders, returns, and shipping information of customers. +- **Sales Analytics:** Visualize the sales data, identify the trends, and prepare reports to guide the business in those decisions. + +### Healthcare Administration + +- **Patient Records:** Securely manage patient information, appointment schedules, and medical history. +- **Billing Systems:** Manage the billing process, insurance claims, and payment tracking. +- **Resource Allocation:** Monitor resource availability and the use of health resources: human, equipment, and facilities. + +### Education Management + +- **Student Information Systems:** For the maintenance of the record of students, enrollment, attendance, grades, and progress reports. +- **Course Management:** Creation, updating, and organizing course materials, schedules, and assignments. +- **Performance Analytics:** Analyze data about student performance for improving their weaknesses and bettering methods of teaching. + +### Financial Services + +- **Portfolio Management:** Manage investment portfolios; monitor the performance of assets; develop financial reports. +- **Risk Assessment:** Monitoring and Assessment of financial risks, compliance, and regulatory requirements. +- **Transaction Tracking:** Tracks and maintains records of financial transactions, account balances, and client information. + +### Logistics and Supply Chain + +- **Fleet Management:** Monitor the locations of vehicles, manage routes and track the status of deliveries at any point. +- **Warehouse Management:** Optimizes warehouse operation, inventory levels, and shipment management. +- **Supplier Coordination:** Contact suppliers, track ordered goods, and ensure that the goods are delivered on time. ## Conclusion