How ChatGPT helped me build an awesome React component
Tags: chatgpt, react, programming, typescript
Published: 2023-10-13 21:23:47

## Introduction :newspaper:

In this article, I'm going to tell you how I used ChatGPT to help me find a solution to a problem that I faced while creating a React component.

I needed to create an Table Component for a Design System, where inside were an HTML Table but I didn't create the same as a HTML Table or as usually passing two parameter, first one the data and second one the rest configs. 
I wanted to create something mixed, using Composite Pattern where would be an Table Root receiving data and its configs and then Column as a children receiving its own data and configs.
I choose this pattern because I thought that in the future it could grow with many other behaviors but without affect others.

---

## The Problem :warning:

When I created this proposal, the problems and questions I faced were: 

- How would I set up the HTML structure if the data was in Table but the necessary information to create the the TR and TH THML tags were in the children of Column component?

- How can I get access to data and then set up the HTML table?

See the example bellow:

```typescript
export interface TableRootProps {
    values: any[],
    children: ReactElement | ReactElement[] | null;
    title?: string;
    hasTotalizer?: boolean;
    maxHeight?: string
}

function TableRoot({
                        title, 
                        children = null, 
                        values, 
                        hasTotalizer = false,
                        maxHeight = '430px',
                        ...props
                    }: TableRootProps) 
{
    return (
        <table>
            <thead>
                <tr>
                    HEADER DATA
                </tr>
            </thead>
            <tbody>
                CONTENT DATA
            </tbody>
            
        </table>
    )
}

export interface ColumnProps {
    header: string,
    field: string,
    sortable?: boolean,
    maxWidth?: string,
    dataType: string,
    chipped?: boolean,
    format?: string,
    visible?: boolean,
}

function TableColumn( {visible = true, ...props} : ColumnProps) {
    return null;
}

TableRoot.displayName = 'Table.Root';
TableColumn.displayName = 'Table.Column';

export const Table =
{ 
    Root: TableRoot,
    Column: TableColumn,
};
```

My barrier was to find an way to get the HeaderData and the ContentData in the same location because some datas were separated in some Column components.

I began to research about the React more deeply to understand a way to did this and I found the React Chidren! 
It allow us to manipulate the children props.

But I was making one mistake. I was trying to manipulate the data inside Children in some way.

My thoughts were going the wrong way and I didn't know a way to clear that path.

Were at that moment that I decided to share this difficult with ChatGPT.

---

## ChatGPT And My Question :atom_symbol:

I explained to ChatGPT my context giving it the information about Stack, Composite Pattern and then I asked how can I get the data to build the table.

After trying several questions I arrived at this final question bellow that gives me a conceptual answer and a code example to better understand.

### My "Question" and The Solution :interrobang:
 
> _Make an App with React and TypeScript._
> _This app has a functional component called TableRoot that receive as a children using composition two functional components called TableColumn and TableAction._
> _The TableColumn has only an header and a field as a properties._
> _TableAction has only an icon and a click event as a properties and must be receive all data by properties._
> _The TableRoot must be return as a result an HTML table with 3 columns of type TableColumn and with 3 lines with all values dynamic, besides, one column of type TableAction with they properties with eyes icon and click event receiving one parameter containing all values of line and then show it on console._ 
> _The click event parameter of TableAction, must be created in main App and then passed as a property to TableAction._
> _All data must be created in main App and then passed by properties._

:x: **Attention: _Do not copy the answer code and use it directly. Try to understand how it works, what the concept is behind it and try to create it in your own codes using the logic of the answer as a basis._**

There are many details in one question, I know it, but how much details we provide to ChatGPT is better. Maybe, we don't provide many details, but it has worked for me.

If you observe, I provided my component structure in details. I already built all structure with my properties, names, patterns and provided it to ChatGPT for its focus in my problem, which was children.

And then... it were on target! :dart:

The ChatGPT gave me an answer that I was waiting for. 
The answer contained the missing detail for me to complete my puzzle. 
The informations about how to use the Children to catch values in children's property cloning children and getting data by properties.

I was able to understand the concept behind the resource and also saw how to apply it.

The code has many information but i'll show bellow part of the code that made the difference.

```typescript
//Getting the properties of child columns
Children.forEach(children, (child) => {
  if(child?.type === TableColumn)
      propertiesFromColumnChildren.push(child?.props);
});

//Treating the values ​​for those that should be displayed
const treatingValues = (value: any) =>{

  if(!propertiesFromColumnChildren){
      return [];
  }

  return propertiesFromColumnChildren.reduce(function(acc, item) {
      acc[item.field] = value[item.field];
      return acc;
  }, {});
};

useEffect(() => {
  tableData = values.map(treatingValues);
  setFilteredTableData(tableData);
}, [values])

//Creating the HTML table body
const creatingTableBody = (item: object, iTr: Key | null | undefined)=>{
  return (
      <tr key={`tr${iTr}`}>
          {
              Children.map(children, (child: any, iTd) => returnCellElementByType(child, item, iTd))
          }
      </tr>
  )
}

//Part of the returnCellElementByType metohd that clones the contents of the children
{React.cloneElement(child, { children: child.props.children, onClick: child.props.onClick(item)})}

```

To see the all code and more details click [here on the code on GitHub](https://github.com/JVidalN/design-system/blob/master/src/components/Table/Table.tsx)

---

## Conclusion :bulb:

Finally, I can say that ChatGPT can actually help us developers learn, code better and, over time, increase our productivity.

But, we need to be careful. Beloware some of my thoughts.

* We can use the ChatGPT as a "copilot", helping in specific doubts or to learn how to refactor the code.
* The code generated by ChatGPT shouldn't be copied and used in your application. If you want to learn and improve yourself, you first need understand what your question is, what you need to fix and then ask a specific question and understand the ChatGPT's response, considering your context.
* You need make the questions correctly. The ChatGPT needs context to create a more fitable response.
* Not all answers will be correct. You need read it and understand if this will make sense to you.

I think of ChatGPT as another good tool to help me be more productive, but the thinking beings are still us, the developers.

I hope you liked it. :+1:
Comment what you think, give me feedbacks and see you! :wave:

---

## Links
* [Design System Repository](https://github.com/JVidalN/design-system)
* [How I built this Design System](https://dev.to/jvidaln/what-is-design-system-and-how-to-build-it-30ad)