# Component Pattern

## Controlled / Uncontrolled Component

### Controlled Component

* Controlled components are form elements (like `input`, `textarea`, or `select`) that are managed by React state.&#x20;

```jsx
import React, { useState } from 'react';

function ControlledComponent() {
  const [value, setValue] = useState('');

  const handleChange = (event) => {
    setValue(event.target.value);
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    alert('A name was submitted: ' + value);
  };

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Name:
        <input type="text" value={value} onChange={handleChange} />
      </label>
      <button type="submit">Submit</button>
    </form>
  );
}

export default ControlledComponent;
```

### Uncontrolled Component

* Uncontrolled components in React manage their own state internally rather than relying on React state.
* Using the `ref` attribute to create a reference (`this.inputRef`) to the DOM node of the input field to access the internal state

```jsx
import React, { useRef } from 'react';

function UncontrolledComponent() {
  const inputRef = useRef(null); // Create a ref to hold the input DOM element

  const handleSubmit = () => {
    // Access the input value using the ref
    console.log(inputRef.current.value);
  };

  return (
    <div>
      <input type="text" ref={inputRef} />
      <button onClick={handleSubmit}>Submit</button>
    </div>
  );
}

export default UncontrolledComponent;
```

### Pro & Con

#### Controlled Component

* Using controlled components ensures that the form data is always in sync with the React state. This predictability comes from having a single source of truth for the data and easier to debug
* Easier to integrate with form library, e.g: `React Hook Form`

#### Uncontrolled Component

* Applicable for the form that is straightforward with minimal input fields and does not require complex validation or dynamic updates based on other form inputs.
* Validation logic often involves accessing and checking each input's value directly through refs (`ref.current.value`). This approach can lead to more manual and error-prone validation code, especially in forms with complex validation requirements.

## Composable Component

```tsx
import { createFileRoute } from "@tanstack/react-router";
import MyTable from "../../components/myTable";

export const Route = createFileRoute("/_authenticated/my-table")({
  component: () => <MyTablePage />,
});

const MyTablePage = () => {
  return (
    <MyTable>
      <MyTable.Search />
      <MyTable.Table />
      <MyTable.Pagination />
    </MyTable>
  );
};
```

```tsx
import { ColumnDef, createColumnHelper } from "@tanstack/react-table";
import React from "react";
import { Product } from "../../types/my-table";
import Checkbox from "./checkBox";
import Row from "../layout/row";
import CustomTable from "./customTable";
import CustomSearch from "./customSearch";
import CustomPagination from "./customPagintaion";
import useMyTable from "../../hooks/my-table/useMyTable";
import TableContext from "../../contexts/tableProvider";

interface Props {
  children: React.ReactNode;
}
const MyTable = ({ children }: Props) => {
  const columnsHelper = createColumnHelper<Product>();
  const columns: ColumnDef<Product, any>[] = [];
  const { table } = useMyTable(columns);

  return (
    <TableContext.Provider value={{ table }}>
      <div className="relative overflow-x-auto shadow-md sm:rounded-lg py-10 px-5">
        {children}
      </div>
    </TableContext.Provider>
  );
};
MyTable.Search = CustomSearch;
MyTable.Table = CustomTable;
MyTable.Pagination = CustomPagination;
export default MyTable;
```

* Easy to implement container & presentation pattern, state management & logic is on parent component (container layer)  and pass the prop into child-component (presentation layer) through implementing context provider
* Easier to understand the relationship between components and clear structure
* Suitable to implement it with `Form` , `Table`

## References

{% embed url="<https://dev.to/ricardolmsilva/composition-pattern-in-react-28mj>" %}

{% embed url="<https://www.freecodecamp.org/news/what-are-controlled-and-uncontrolled-components-in-react/>" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://petercheng7788.gitbook.io/developer-note/frontend/react/core/component-pattern.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
