# useNuiMutation

## Overview

The `useNuiMutation` hook provides an easy and effective way to send mutations _(i.e., actions that modify data or trigger side effects)_ to the FiveM client in a React-based environment. It simplifies the process of interacting with the NUI (Native UI) system by sending requests and handling responses with custom callbacks.

{% hint style="warning" %}
Use `useNuiMutation` for sending data (e.g., handle click), as it's designed for mutations, while `useNuiQuery` is for fetching data.
{% endhint %}

## Usage

### Importing the Hook

```tsx
import { useNuiMutation } from "@yankes/fivem-react/hooks";
```

### Parameters

`useNuiMutation` does not require any parameters for initialization. However, when invoking the `mutate` function, you have to pass the following parameters:

<table><thead><tr><th>Parameter</th><th width="187">Type</th><th>Description</th><th data-type="checkbox">Optional</th></tr></thead><tbody><tr><td><strong><code>endpoint</code></strong></td><td><code>string</code></td><td>Endpoint where you send NUI Callback.</td><td>false</td></tr><tr><td><strong><code>options</code></strong></td><td><a href="#options"><code>Options</code></a></td><td>Additional options</td><td>true</td></tr></tbody></table>

### Options

Object contains parameters below _(all parameters are optional)_:

| Parameter       | Type                                                                       | Description                                                                                                                            |
| --------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| **`body`**      | `string \| number \| boolean \| Array<unknown> \| Record<string, unknown>` | The `body` parameter contains the data sent with the NUI request, supporting various types without requiring manual string conversion. |
| **`onSuccess`** | `(value: Response \| void) ⇒ void \| PromiseLike<void>`                    | The `onSuccess` callback is triggered on a successful NUI response, receiving the data for further processing.                         |
| **`onError`**   | `(reason: unknown) ⇒ void \| PromiseLike<void> \| null \| undefinded`      | The `onError` callback is triggered if the NUI request fails, allowing error handling or recovery actions.                             |
| **`onFinally`** | `() ⇒ void \| null \| undefinded`                                          | The `onFinally` callback runs after the NUI request completes, regardless of success or failure, for cleanup or final actions.         |

### Return Value

The hook returns an object with the following properties:

| Name            | Type                                                           | Description                                                                                                                                                               |
| --------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`mutate`**    | `(endpoint: string, options?:` [`Options`](#options)`) ⇒ void` | A function that accepts an `endpoint` string and an optional `options` object. The `mutate` function sends the NUI mutation request.                                      |
| **`isPending`** | `boolean`                                                      | A boolean state indicating whether the mutation is currently in progress. It can be used to show loading indicators or disable UI elements while the mutation is pending. |



## Example

### ReactJS

```tsx
import { useState } from "react";
import { useNuiMutation } from "@yankes/fivem-react/hooks";

export const MyComponent = () => {
    const [message, setMessage] = useState("");
    const { mutate, isPending } = useNuiMutation();

    const handleSubmit = async () => {
        mutate("/send-message", {
            body: { message },
            onSuccess: (response) => {
                console.log("Message sent successfully", response);
                setMessage("");
            },
            onError: (error) => {
                alert("Failed to send message");
            },
            onFinally: () => {
                console.log("Mutation process complete");
            }
        });
    };

    return (
        <div>
            <input
                type="text"
                value={message}
                onChange={(e) => setMessage(e.target.value)}
                disabled={isPending}
            />
            <button onClick={handleSubmit} disabled={isPending}>
                {isPending ? "Sending..." : "Send Message"}
            </button>
        </div>
    );
};
```

### LUA

```lua
RegisterNUICallback("send-message", function(data, cb)
    if data.message then
        ExecuteCommand(data.message)
        cb(true)
    else
        cb(false)
    end
end)

```

### How It Works

1. The `useNuiMutation` hook initializes a `mutate` function and a `isPending` state.
2. When the `mutate` function is called, it receives an `endpoint` and an optional `options` object containing data and callbacks.
3. The `mutate` function uses `startTransition` to manage the mutation process, ensuring the UI remains responsive.
4. The `fetchNui` function sends the NUI request to the FiveM client with the specified `endpoint` and `body` data.
5. If the request is successful, the `onSuccess` callback is triggered, allowing the response to be processed.
6. If an error occurs during the mutation, the `onError` callback is executed to handle the error.
7. After the mutation process completes, regardless of success or failure, the `onFinally` callback is called for cleanup operations.
8. The `isPending` state is updated based on whether the mutation is still in progress, allowing the UI to reflect the current request status (e.g., showing loading indicators or disabling UI elements).

## Notes

* The hook provides flexible callbacks (`onSuccess`, `onError`, and `onFinally`) for handling the response lifecycle in a structured manner.
* The mutation request lifecycle is managed automatically, eliminating the need for manual cleanup.
* The `isPending` state helps track the request status, enabling dynamic UI behavior, such as displaying loading spinners or disabling buttons while the request is in progress.
* The hook abstracts away the complexity of dealing with NUI requests, allowing you to focus on handling the response and UI interactions.

## Conclusion

The `useNuiMutation` hook provides a straightforward and flexible way to handle mutations within a React-based FiveM environment. It abstracts away the complexity of managing NUI requests, keeping your code clean, responsive, and easy to maintain.
