Skip to content

Commit

Permalink
Merge branch 'master' into releases/july
Browse files Browse the repository at this point in the history
  • Loading branch information
BatuhanW authored Jul 1, 2024
2 parents 311dcdc + 2736a21 commit 41d877d
Show file tree
Hide file tree
Showing 61 changed files with 4,446 additions and 779 deletions.
2 changes: 1 addition & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Please check if your PR fulfills the following requirements:

## What is the new behavior?

fixes # (issue)
fixes (issue)

## Notes for reviewers

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ description: We'll cover what React Fragments are, differences between React Fra
slug: how-react-fragments-is-works
authors: clara_ekekenta
tags: [react]
image: https://refine.ams3.cdn.digitaloceanspaces.com/blog/2022-10-02-react-fragments/social.png
image: https://refine.ams3.cdn.digitaloceanspaces.com/blog/2022-10-02-react-fragments/social-2.png
hide_table_of_contents: false
---

**This article was last updated on Jun 26, 2024, to add new advantages, use cases and common problems sections for React Fragments**

## Introduction

Returning multiple elements from a component has always been problematic for React developers.
Expand All @@ -21,9 +23,12 @@ Steps we'll cover:
- [React Fragment vs Div Element](#react-fragment-vs-div-element)
- [Problem with using div](#problem-with-using-div)
- [Advantages of Fragment](#advantages-of-fragment)
- [Limitations of React Fragments](#limitations-of-react-fragments)
- [Using the key prop with React fragments](#using-the-key-prop-with-react-fragments)
- [Using shortcut version](#using-shortcut-version)
- [Fragment in Action](#fragment-in-action)
- [Other Use Cases for a React Fragment](#other-use-cases-for-a-react-fragment)
- [Common Problems and Solutions](#common-problems-and-solutions)

## What is React Fragment?

Expand Down Expand Up @@ -99,6 +104,16 @@ React Fragment replaces the `<div>` element, which can cause issues with invalid
- React Fragment allows React components to be rendered as intended without causing any parent-child relationship issues.
- Fragments allow the return of multiple JSX elements, which addresses the issue of invalid HTML markups within react applications that were caused by the must-have constraint of only one element returning per component.

### Limitations of React Fragments

I just wanted to point out a few things you should be aware of regarding React Fragments. Although they are great for grouping elements without having to add an extra node in the DOM, there are limitations to them.

First off, it is not possible to apply any CSS styles to a Fragment directly as Fragments are not fundamental DOM elements and do not render any actual element. This means that when you want to style a collection of elements, you are forced to still wrap them with a `<div>` or other such container element.

In the case of fragments, you can't use keys. That can sometimes be a little frustrating when you work with lists of children. Keys help React identify which items have changed or been added or removed. Without the ability to assign keys, managing dynamic lists becomes tricky.

Finally, when we do this cleanup of the DOM, sometimes Fragments make the JSX a bit harder to read if overused. It is essential that they be used wisely; not every `<div>` must be replaced with a Fragment just for it.

## Using the key prop with React fragments

In some cases, the key prop is required in a React application. In react, the key props are typically used to control component instances. React uses the key prop in scenarios like this to identify which items changed, removed, or added. Using the key props in a React application with fragments will be like the code snippet below.
Expand Down Expand Up @@ -186,6 +201,105 @@ export default App;

In the above code snippet, we created two components that we to be rendered in our application. In the render method, we used React Fragment instead of wrapping the elements in the TableData components in a div. This way, our table data will be rendered as expected.

### Other Use Cases for a React Fragment

React Fragments come in really handy when handling lists of elements, forms, and complex layouts. Using Fragments in a list would clean up the DOM, saving you from creating wrapper elements that are not needed for this to increase performance.

For forms, it helps ease the structure without adding more nodes because of multiple input elements. Furthermore, with complex layouts, when the nesting of elements is there, Fragments controls and manages the layout for proper handling and styling. Fragments make sure that the structure of a table is valid when the rows and cells of the table are being rendered; it ensures there are no layout-related problems.

React Fragments, conversely, help with conditional rendering because they enable you to return several elements depending on some conditions—but without adding nodes, which would make your DOM dirty and your components complex to read and maintain. In any case, the use of fragments in this context helps enhance the readability, performance, and maintainability of your applications.

### Common Problems and Solutions

Below are some common issues one is likely to face while working with React Fragments and how to resolve them.

#### 1. **Invalid HTML Structure**

**Issue:** My HTML structure is invalid when using Fragments.

**Solution:** Ensure there is no breakage of HTML rules; for example, if you place table cells (`<td>`) outside the table row (`<tr>`). Use fragments properly to maintain structural validity.

```jsx
function TableData() {
return (
<>
<td>Eat</td>
<td>Learn</td>
<td>Code</td>
</>
);
}
```

#### 2. **Cannot Apply Styles**

**Issue:** I can't apply styles to a Fragment.

**Solution:** As fragments do not render any DOM elements, you can't apply styles directly. If you want to style these elements, wrap them in a `<div>` or some other appropriate container.

```jsx
function StyledComponent() {
return (
<div className="styled-container">
<h1>Title</h1>
<p>Paragraph</p>
</div>
);
}
```

#### 3. **Keyed Fragments**

**Issue:** I need to use keys with my Fragments, yet the short-hand syntax doesn't support it.

**Solution:** In cases where you need to pass keys, use the extended syntax for Fragments.

```jsx
function ListItems({ items }) {
return (
<>
{items.map((item) => (
<React.Fragment key={item.id}>
<li>{item.name}</li>
<li>{item.description}</li>
</React.Fragment>
))}
</>
);
}
```

#### 4. **Fragment Overuse**

**Problem:** My JSX is getting hard to read as it has too many Fragments.

**Solution:** Use Fragments judiciously. Only use them when absolutely necessary to not unnecessarily convolute your JSX.

#### 5. **Unexpected Rendering Behavior**

**Problem:** Fragments of enclosed objects are not displayed as expected.

**Solution:** Confirm if your Fragments are correctly placed, and you haven't omitted any closing tags. Also see to it that you write your component logic correctly.

#### 6. **Debugging Problems**

**Issue:** Since the Fragments are not directly visible in the DOM, debugging becomes hard.

**Solution:** Use descriptive comments or temporary wrappers while debugging. Remove the wrappers once you've resolved the issues.

```jsx
function DebugComponent() {
return (
// <div> /* debugging temporary wrapper */
<>
<h1>Title</h1>
<p>Paragraph</p>
</>
// </div>
);
}
```

## Conclusion

Throughout this tutorial, you've learned about React Fragment. We started by knowing what a React Fragment is and when to use it in a React application. Then we went further to demonstrate how it's used in a practical application.
43 changes: 25 additions & 18 deletions examples/multi-tenancy-strapi/index.html
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Web site created using refine" />
<!--
<head>
<meta charset="utf-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Web site created using refine" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"
rel="stylesheet"
/>
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<title>
refine - A React-based framework for building data-intensive
applications in no time.
</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" src="/src/index.tsx"></script>
<title>
refine - A React-based framework for building data-intensive applications
in no time.
</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="module" src="/src/index.tsx"></script>

<!--
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
Expand All @@ -29,5 +35,6 @@
To begin the development, run `npm run dev` or `yarn dev`.
To create a production bundle, use `npm run build` or `yarn build`.
--></body>
-->
</body>
</html>
5 changes: 4 additions & 1 deletion examples/multi-tenancy-strapi/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
"@refinedev/react-router-v6": "^4.5.11",
"@refinedev/strapi-v4": "^6.0.8",
"antd": "^5.17.0",
"antd-style": "^3.6.1",
"axios": "^1.6.2",
"lucide-react": "^0.336.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react-router-dom": "^6.8.1"
Expand All @@ -40,6 +42,7 @@
"@types/react-dom": "^18.0.0",
"@vitejs/plugin-react": "^4.2.1",
"typescript": "^5.4.2",
"vite": "^5.1.6"
"vite": "^5.1.6",
"vite-tsconfig-paths": "^4.2.1"
}
}
55 changes: 55 additions & 0 deletions examples/multi-tenancy-strapi/src/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
.ant-pagination-item {
border-radius: 100% !important;
font-weight: 400 !important;
}

.ant-pagination-item-active {
border-radius: 100% !important;
color: var(--ant-color-primary-text-active) !important;
background: var(--ant-color-primary-bg) !important;
border: 1px solid var(--ant-color-primary-bg-hover);
}

.ant-table-content {
border: 1px solid var(--ant-color-border);
border-radius: 24px;
}

.ant-pagination-total-text {
margin-right: auto;
margin-inline-end: auto !important;
}

.ant-table-cell {
white-space: nowrap;
}

.ant-btn {
border-radius: 80px;
}

.ant-form-item-horizontal {
.ant-form-item-row {
align-items: center;
}
}

.ant-table-filter-dropdown > div > div {
width: 100%;
}

.ant-select {
width: 100%;
}

.ant-select-selector {
width: 100%;
}

.ant-page-header-heading {
height: 56px;

@media screen and (max-width: 768px) {
height: max-content;
}
}
Loading

0 comments on commit 41d877d

Please sign in to comment.