diff --git a/README.md b/README.md index 4f54a38..58885a9 100644 --- a/README.md +++ b/README.md @@ -2,101 +2,57 @@ A somewhat flexible react hook alternative to `React.useReducer`. Written in Typescript. -[Demo Playground](https://codesandbox.io/p/sandbox/react-hook-use-cta-7jnc32?file=%2Fsrc%2FApp.tsx) - -## Table of Contents +# Table of Contents - [Installation](#installation) - [NPM](#npm) -- [export { useCTA }](#export--usecta-) - - [Usage](#usage) - -
- -Table of Contents: Parameter - -- [Parameter](#parameter) - - [initial](#parameter-initial) - - [onInit](#parameter-oninit) - - [actions](#parameter-actions) - - [Predefined actions](#predefine-actions) - - [actions?.\['customAction'\]](#parameter-actionscustomaction) - - [Parameter](#parameter-actionscustomaction) - 1. [1st Parameter: CustomCTAParam](#actionscustomaction-1st-parameter-customctaparam) - - [replaceAction](#actionscustomaction-1st-parameter-customctaparamreplaceaction) - - [replaceInitialAction](#actionscustomaction-1st-parameter-customctaparamreplaceinitialaction) - - [resetAction](#actionscustomaction-1st-parameter-customctaparamresetaction) - - [updateAction](#actionscustomaction-1st-parameter-customctaparamupdateaction) - 2. [2nd Parameter: payload](#actionscustomaction-2nd-parameter-payload) - - [Return Type](#actionscustomaction-return-type) - -
- -
- -Table of Contents: Return Type - -- [Return Type](#return-type) - 1. [state](#return-type-state) - 2. [dispatch](#return-type-dispatch) - - [dispatch.cta](#return-type-dispatchcta) - - [dispatch.cta?.\['customAction'\]](#return-type-dispatchctacustomaction) - - [dispatch.cta?.\['customAction'\] with `payload` parameter](#return-type-dispatchctacustomaction-with-payload-parameter) - - [dispatch.cta?.\['customAction'\] without parameter](#return-type-dispatchctacustomaction-without-parameter) - - [dispatch.cta.update](#return-type-dispatchctaupdate) - - [dispatch.cta.update with `payload` parameter](#return-type-dispatchctaupdate-with-payload-parameter) - - [dispatch.cta.update with `key` and `value` parameters](#return-type-dispatchctaupdate-with-key-and-value-parameters) - - [dispatch.cta.replace](#return-type-dispatchctareplace) - - [dispatch.cta.replaceInitial](#return-type-dispatchctareplaceinitial) - - [dispatch.cta.reset](#return-type-dispatchctareset) - - [dispatch.cta.reset without parameter](#return-type-dispatchctareset-with-payload-parameter) - - [dispatch.cta.reset with `payload` parameter](#return-type-dispatchctareset-without-parameter) - - [dispatch.state](#return-type-state) - - [dispatch.state.current](#return-type-dispatchstatecurrent) - - [dispatch.state.initial](#return-type-dispatchstateinitial) - - [dispatch.state.changes](#return-type-dispatchstatechanges) - - [dispatch.state.previous](#return-type-dispatchstateprevious) - -
+- [useCTA](#usecta) +- [createCTAContext](#createctacontext) + - [CTAProvider](#ctaprovider) + - [useCTAStateContext](#usectastatecontext) + - [useCTAStateContext](#usectadispatchcontext) +
-Table of Contents: Typescript exports +Table of Contents: Typescript helper and exports +- [returnActionsType](#returnactionstype) - [Typescript exports](#typescript-exports) - - [export type { CTAInitial, }](#export-type--ctainitial-) - - [export type { UseCTAParameter, }](#export-type--usectaparameter-) - - [export type { UseCTAReturnType, }](#export-type--usectareturntype-) - - [export type { UseCTAReturnTypeDispatch, }](#export-type--usectareturntypedispatch-) - - [export type { UseCTAReturnTypeDispatchState, }](#export-type--usectareturntypedispatchstate-) + - [CTAInitial](#export-type--ctainitial-) + - [UseCTAParameter](#export-type--usectaparameter-) + - [UseCTAReturnType](#export-type--usectareturntype-) + - [UseCTAReturnTypeDispatch](#export-type--usectareturntypedispatch-) + - [CustomCTAStateParam](#export-type--customctastateparam-) + - [CTAStateParam](#export-type--ctastateparam-) + - [CustomCTAReturnType](#export-type--customctareturntype-)
- --- -## Installation +# Installation ``` -react-hook-use-cta fast-equals +react-hook-use-cta ``` -### NPM +## NPM ```bash -npm i react-hook-use-cta fast-equals +npm i react-hook-use-cta ``` --- -## `export { useCTA }` +# useCTA -https://github.com/rafde/react-hook-use-cta/blob/9e9206f1ff06e2de5adcde5d107d9d847e210063/src/index.ts#L9-L14 +
-### Usage +Basic example code ```tsx -import { useEffect, } from "react"; +import { useEffect, } from 'react'; import { useCTA, } from 'react-hook-use-cta' function View() { @@ -112,24 +68,32 @@ function View() { }); useEffect( - () => dispatch.cta.update('search', 'update'), + () => dispatch.cta.update('search', 'update search'), [] ); - /* Renders `update` */ - return <>{state.search} + /* Renders `update search` */ + return state.search; } ``` +
+
-Example using all useCTA parameters +Advance example code ```tsx -import { useEffect, } from "react"; -import { useCTA, } from 'react-hook-use-cta' +import { useEffect, } from 'react'; +import { useCTA, CustomCTAStateParam, CTAStateParam, } from 'react-hook-use-cta' -function View(props: { initial: { search: string, isFuzzy: boolean, count: 0 } }) { +type ViewPropsInitial = { + search: string + isFuzzy: boolean + count: number +}; + +function View(props: { initial: ViewPropsInitial }) { const [ state, dispatch, @@ -143,22 +107,22 @@ function View(props: { initial: { search: string, isFuzzy: boolean, count: 0 } } }, actions: { // START: augment predefined actions - replace(ctaParam, payload) { + replace(ctaStateParam: CTAStateParam, payload) { return payload; }, - replaceInitial(ctaParam, payload) { + replaceInitial(ctaStateParam: CTAStateParam, payload) { return payload; }, - reset(ctaParam, payload) { + reset(ctaStateParam: CTAStateParam, payload) { return payload; }, - update(ctaParam, payload) { + update(ctaStateParam: CTAStateParam, payload) { return payload; }, // END: augment predefined actions // START: Custom actions - toggleIsFuzzy(ctaParam, isFuzzy?: boolean) { + toggleIsFuzzy(customCTAStateParam: CustomCTAStateParam, isFuzzy?: boolean) { if (typeof isFuzzy === 'undefined') { return { isFuzzy: !ctaParam.previous.isFuzzy, @@ -169,12 +133,12 @@ function View(props: { initial: { search: string, isFuzzy: boolean, count: 0 } } isFuzzy } }, - addToCount(ctaParam, value: number) { + addToCount(customCTAStateParam: CustomCTAStateParam, value: number) { return { count: ctaParam.previous.count + value, } }, - incrementCount(ctaParam) { + incrementCount(customCTAStateParam: CustomCTAStateParam) { return { count: ctaParam.previous.count + 1, } @@ -193,7 +157,7 @@ function View(props: { initial: { search: string, isFuzzy: boolean, count: 0 } }
{dispatch.state.initial.search}
{dispatch.state.changes?.search}
{dispatch.state.previous.search}
- + ; } ``` @@ -203,1056 +167,1691 @@ function View(props: { initial: { search: string, isFuzzy: boolean, count: 0 } } ## Parameter -**Required** - -Key/value `object` of type `UseCTAParameter` - -https://github.com/rafde/react-hook-use-cta/blob/9e9206f1ff06e2de5adcde5d107d9d847e210063/src/types/UseCTAParameter.ts#L4-L11 - -Typescript Definition: -- [CTAInitial](#export-type--ctainitial-) - ---- - -### Parameter: `initial` - -**Required** - -https://github.com/rafde/react-hook-use-cta/blob/1e97f6ef6c5bc3d053cf64007bfea7c5c84877a0/src/types/UseCTAParameter.ts#L9 - -Similar to `React.useReducer` `initialArg` parameter, -but it only takes key/value `object` that defines the shape of your [state](#return-type-state). - -Values can be anything that -[strictDeepEqual](https://github.com/planttheidea/fast-equals/tree/v5.0.1?tab=readme-ov-file#strictdeepequal) -from [fast-equals](https://github.com/planttheidea/fast-equals/tree/v5.0.1?tab=readme-ov-file#fast-equals) -supports. - -Typescript Definition: -- `Initial` extends [CTAInitial](#export-type--ctainitial-) - ---- - -### Parameter: `onInit` +Typescript: +- [UseCTAParameter](#export-type--usectaparameter-) -_Optional_ +[useCTA](#usecta) accepts an `object`, that is read once, with the following properties: -https://github.com/rafde/react-hook-use-cta/blob/1e97f6ef6c5bc3d053cf64007bfea7c5c84877a0/src/types/UseCTAParameter.ts#L10 +### `initial` -Similar to `React.useReducer` `init` parameter. Called on first time render. A `function` that is called to replace [initial](#parameter-initial) value. +> [!IMPORTANT] +> A **required** `object` representing the initial state. +> Property values can be anything that [strictDeepEqual](https://github.com/planttheidea/fast-equals/tree/v5.0.1?tab=readme-ov-file#strictdeepequal) +> from [fast-equals](https://github.com/planttheidea/fast-equals/tree/v5.0.1?tab=readme-ov-file#fast-equals) supports. -Typescript Definition: -- `Initial` extends [CTAInitial](#export-type--ctainitial-) - ---- - -### Parameter: `actions` - -_Optional_ - -Read once on first time render. Key/value `object` to define the types of actions to implement. - -The following results will **not** trigger re-render for all actions: -- Returning a falsy value. -- Returning a non-`null` `object` that doesn't change the values of [state](#return-type-state) -or [dispatch.state.initial](#return-type-dispatchstateinitial) - -#### Predefine actions - -There are predefined actions that can be augmented with the following signatures: - -https://github.com/rafde/react-hook-use-cta/blob/7532ce5d41502f3fc9a0b0275ba2eaae7c2c16fe/src/types/UseCTAParameterActionsPredefinedRecord.ts#L4-L9 - -Augmenting these actions will affect custom actions. - -Typescript Definition: -- [CTAInitial](#export-type--ctainitial-) -- [UseCTAReturnTypeDispatchState](#export-type--usectareturntypedispatchstate-) - -Predefined calls to action: - -- [dispatch.cta.update](#return-type-dispatchctaupdate) -- [dispatch.cta.replace](#return-type-dispatchctareplace) -- [dispatch.cta.replaceInitial](#return-type-dispatchctareplaceInitial) -- [dispatch.cta.reset](#return-type-dispatchctareset) - ---- - -#### Parameter: `actions?.['customAction']` - -You can define your own custom actions to handle -[payload](#actionscustomaction-2nd-parameter-payload)s to your specifications. - -Typescript signature: - -https://github.com/rafde/react-hook-use-cta/blob/adfd2a0448f08a4d1374db0136f77dde9c64da7a/src/types/UseCTAParameterActionsRecordProp.ts#L6-L14 - -Typescript Definitions: +Typescript: - [CTAInitial](#export-type--ctainitial-) -- [CustomCTAParam](#export-type--customctaparam-) -Call to action: +### `onInit` -- [`dispatch.cta?.\['customAction'\]](#return-type-dispatchctacustomaction) - - [dispatch.cta?.\['customAction'\] with payload parameter](#return-type-dispatchctacustomaction-with-payload-parameter) - - [dispatch.cta?.\['customAction'\] without parameter](#return-type-dispatchctacustomaction-without-parameter) +> [!NOTE] +> An _optional_ callback for setting [initial](#initial) `object` on first render. It accepts the [initial](#initial) +> state `object` and returns a new [initial](#initial) state `object`.
-Example for Parameter: actions?.['customAction'] +onInit example code ```tsx -import { useCTA } from 'react-hook-use-cta' +import { useCTA, } from 'react-hook-use-cta' -function View(props: {initial: {search: string, isFuzzy: boolean, count: 0}}) { +function View() { const [ state, - dispatch, ] = useCTA({ - initial: props.initial, + initial: { + search: '', + }, onInit(initial) { return { ...initial, search: 'onInit', } - }, - actions: { - // START: Custom actions - toggleIsFuzzy(ctaParam, payload?: boolean) { - if (typeof payload === 'undefined') { - return { - isFuzzy: !ctaParam.previous.isFuzzy, - } - } - - return { - isFuzzy: payload, - } - }, - addToCount(ctaParam, payload: number) { - const count = ctaParam.previous.count + payload; - if (isNaN(count) || count < 0) { - return; - } - return { - count, - } - }, - incrementCount(ctaParam) { - return { - count: ctaParam.previous.count + 1, - } - }, - // END: Custom actions } }); - - useEffect( - () => dispatch.cta.addToCount(4), - [] - ); - - return <>{state.count} + + // renders `onInit` + return state.search; } ```
---- - -##### `actions?.['customAction']` 1st Parameter: `CustomCTAParam` - -Custom actions' first parameter: - -https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/types/CustomCTAParam.ts#L11-L16 - -extends [UseCTAReturnTypeDispatchState](#return-type-dispatchstate) -with 4 additional functions that affect the behavior of the action. +### `actions` -https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/types/CustomCTAParam.ts#L12-L15 - -Accepts `result` and `options` - -https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/internal/ActionTypes.ts#L8 - -If predefined actions were augmented, `{useCustom: false}` will bypass them and use default predefined behavior. +> [!NOTE] +> An _optional_ `object` for augmenting [call to actions](#call-to-actions) +> or to create your own [custom call to actions](#custom-actions) --- -###### `actions?.['customAction']` 1st Parameter: `CustomCTAParam.replaceAction` - -https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/types/CustomCTAParam.ts#L12 +## Return -Returns instance of `ReplaceActionType` +https://github.com/rafde/react-hook-use-cta/blob/3fe7f0359362f5e5e35f0776b5c67da6eae5c613/src/types/UseCTAReturnType.ts#L4-L10 -https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/internal/ActionTypes.ts#L26 +> [!NOTE] +> An `array` with 2 values: -Returning `ReplaceActionType` will produce the same outcome as [dispatch.cta.replace](#return-type-dispatchctareplace) +### Current State -
+> [!NOTE] +> A read-only `object` that is set by [initial](#initial) or [onInit](#oninit) on first render. +> It is changed by most [call to actions](#call-to-actions) -Example for CustomCTAParam.replaceAction +### Dispatcher -```ts -const [state, dispatch] = useCTA({ - ///...parameter - actions: { - specialReplace(ctaParam, payload?: boolean) { - if (typeof payload === 'undefined') { - // replace `state` with this new state - return ctaParam.replaceAction({ - ...ctaParam.previous, - isFuzzy: true, - }) - } - - // update state - return { - isFuzzy: payload, - } - }, - }, -}); -``` +> [!NOTE] +> A `function` used to make changes to the current state and trigger re-render. It also includes two properties: -
+#### `cta` ---- +> [!NOTE] +> A read-only `object` for accessing [calls to actions](#call-to-actions) to trigger state change. -###### `actions?.['customAction']` 1st Parameter: `CustomCTAParam.replaceInitialAction` +#### `state` -https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/types/CustomCTAParam.ts#L13 +https://github.com/rafde/react-hook-use-cta/blob/3fe7f0359362f5e5e35f0776b5c67da6eae5c613/src/types/UseCTAReturnTypeDispatch.ts#L256 -Returns instance of `ReplaceInitialActionType` +> [!NOTE] +> A read-only `object` that can be used to reference additional states: +> You have access to the following states -https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/internal/ActionTypes.ts#L43 +##### `state.initial` -Returning `ReplaceIntialActionType` will produce the same outcome as [dispatch.cta.replaceInitial](#return-type-dispatchctareplaceinitial) +> [!NOTE] +> Starts of equal to [initial](#initial) parameter.
-Example for CustomCTAParam.replaceInitialAction - -```ts -const [state, dispatch] = useCTA({ - ///...parameter - actions: { - specialReplaceInitial(ctaParam, payload?: boolean) { - if (typeof payload === 'undefined') { - // replace `initial` with this new state - return ctaParam.replaceInitialAction({ - ...ctaParam.previous, - isFuzzy: true, - }) - } + +The following call to actions can affect it: + - // update state - return { - isFuzzy: payload, - } - }, - }, -}); -``` +- [replaceInitial](#replaceinitial) +- [reset](#reset) +- [custom replaceInitial action](#how-to-define-and-call-custom-action-as-replaceinitial-behavior) +- [custom reset action](#how-to-define-and-call-custom-action-as-reset-behavior)
---- - -###### `actions?.['customAction']` 1st Parameter: `CustomCTAParam.resetAction` +##### `state.current` -https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/types/CustomCTAParam.ts#L14 - -Returns instance of `ResetActionType` - -https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/internal/ActionTypes.ts#L60 - -Returning `ResetActionType` will produce the same outcome as [dispatch.cta.reset with payload parameter](#return-type-dispatchctareset-with-payload-parameter) +> [!NOTE] +> Starts of equal to [initial](#initial) parameter. +> Equivalent to [current state](#current-state).
-Example for CustomCTAParam.resetAction - -```ts -const [state, dispatch] = useCTA({ - ///...parameter - actions: { - specialReplaceInitial(ctaParam, payload?: boolean) { - if (typeof payload === 'undefined') { - // replace `initial` and `state` with this new state - return ctaParam.resetAction({ - ...ctaParam.previous, - isFuzzy: true, - }) - } + +The following call to actions can affect it: + - // update state - return { - isFuzzy: payload, - } - }, - }, -}); -``` +- [update](#update) +- [replace](#replace) +- [reset](#reset) +- [custom update action](#how-to-define-and-call-custom-action-as-update-behavior) +- [custom replace action](#how-to-define-and-call-custom-action-as-replace-behavior) +- [custom reset action](#how-to-define-and-call-custom-action-as-reset-behavior)
---- - -###### `actions?.['customAction']` 1st Parameter: `CustomCTAParam.updateAction` - -https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/types/CustomCTAParam.ts#L15 +##### `state.previous` -Returns instance of `UpdateActionType` +> [!NOTE] +> Starts of equal to [initial](#initial) parameter. Is set to the previous [current state](#current-state). -https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/internal/ActionTypes.ts#L77 +
-Returning `UpdateActionType` will produce the same outcome as [dispatch.cta.update](#return-type-dispatchctaupdate) + +The following call to actions can affect it: + -
- -Example for CustomCTAParam.updateAction - -```ts -const [state, dispatch] = useCTA({ - ///...parameter - actions: { - specialReplaceInitial(ctaParam, payload?: boolean) { - if (typeof payload === 'undefined') { - // replace `initial` and `state` with this new state - return ctaParam.updateAction({ - isFuzzy: true, - }) - } - - // update state - return ctaParam.previous - }, - }, -}); -``` +- [update](#update) +- [replace](#replace) +- [replaceInitial](#replaceinitial) +- [reset](#reset) +- [custom update action](#how-to-define-and-call-custom-action-as-update-behavior) +- [custom replace action](#how-to-define-and-call-custom-action-as-replace-behavior) +- [custom replaceInitial action](#how-to-define-and-call-custom-action-as-replaceinitial-behavior) +- [custom reset action](#how-to-define-and-call-custom-action-as-reset-behavior)
---- - -##### `actions?.['customAction']` 2nd Parameter: `payload` - -`payload`s can be: -- `undefined` -- _optional_ or **required** where the value can be anything -- [Initial](#parameter-initial) type -- `Partial` type - ---- - -##### `actions?.['customAction']` Return Type - -Return type can be -- Falsy value: to **not** trigger re-render. -- `Partial`: triggers re-render if it changes the values of [state](#return-type-state). -Works the same as [CustomCTAParam.updateAction](#actionscustomaction-1st-parameter-customctaparamupdateaction) -- `ReplaceActionType`: See [CustomCTAParam.replaceAction](#actionscustomaction-1st-parameter-customctaparamreplaceaction) -- `ReplaceInitialActionType`: See [CustomCTAParam.replaceInitialAction](#actionscustomaction-1st-parameter-customctaparamreplaceinitialaction) -- `ResetActionType`: See [CustomCTAParam.resetAction](#actionscustomaction-1st-parameter-customctaparamresetaction) -- `UpdateActionType`: See [CustomCTAParam.updateAction](#actionscustomaction-1st-parameter-customctaparamupdateaction) - ---- - -## Return Type - -Array with two values: `[state, dispatch]` of type `UseCTAReturnType` +##### `state.changes` -https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/types/UseCTAReturnType.ts#L4-L10 - -Typescript Definitions: -- [CTAInitial](#export-type--ctainitial-) -- [UseCTAReturnTypeDispatch](#return-type-dispatch) +> [!NOTE] +> Starts of equal to `null`. +> When the property values of [state.initial](#stateinitial) are equal to the [current state](#current-state), the value is `null`. +> Otherwise, it's equal to the difference in property values of [state.initial](#stateinitial) and [current state](#current-state). ---- -### Return Type: `state` +
-Key/value `object` of type [CTAInitial](#export-type--ctainitial-) + +The following call to actions can affect it: + -The current `state`. During the first render, it’s set to the result of [onInit](#parameter-oninit) -or [initial](#parameter-initial) if [onInit](#parameter-oninit) was not defined. +- [update](#update) +- [replace](#replace) +- [replaceInitial](#replaceinitial) +- [reset](#reset) +- [custom update action](#how-to-define-and-call-custom-action-as-update-behavior) +- [custom replace action](#how-to-define-and-call-custom-action-as-replace-behavior) +- [custom replaceInitial action](#how-to-define-and-call-custom-action-as-replaceinitial-behavior) +- [custom reset action](#how-to-define-and-call-custom-action-as-reset-behavior) ---- +
-### Return Type: `dispatch` +#### Dispatcher Parameter -Is type `UseCTAReturnTypeDispatch` +Dispatcher `function` also accepts a parameter object with properties: -https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L219-L225 +##### `type` -Typescript Definition: -- [CTAInitial](#export-type--ctainitial-) +> [!IMPORTANT] +> **Required** `string`. The value is a [call to action](#call-to-actions) name. -A `function` with static read-only properties [dispatch.state](#return-type-dispatchstate) -and [dispatch.cta](#return-type-dispatchcta). +##### `payload` -Triggers re-render when [state](#return-type-state) or [dispatch.state.initial](#return-type-dispatchstateinitial) changes +> [!WARNING] +> A parameter that a [calls to actions](#call-to-actions) can read. +> It's value depends on what a [calls to action](#call-to-actions) can accept. -Parameters description will be covered by: +##### `options` -- [dispatch.cta?.\['customAction'\]](#return-type-dispatchctacustomaction) -- [dispatch.cta.update](#return-type-dispatchctaupdate) -- [dispatch.cta.replace](#return-type-dispatchctareplace) -- [dispatch.cta.replaceInitial](#return-type-dispatchctareplaceinitial) -- [dispatch.cta.reset](#return-type-dispatchctareset) +> [!NOTE] +> _Optional_ key/value `object` that an augmented or custom [call to action](#call-to-actions) may read. --- -#### Return Type: `dispatch.cta` +# Call to Actions -https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L223 +> [!NOTE] +> Call to actions are defined through [actions](#actions) parameter +> and actions are called through [cta](#cta) or [dispatcher](#dispatcher) +> There are call to actions available for immediate use. -Has predefined actions +> [!IMPORTANT] +> When augmenting an existing call to action. The first parameter is always [CTAStateParam](#export-type--ctastateparam-). +> The second parameter depends on what the call to action expects. -https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L192-L198 +## `update` -and custom actions if defined in [actions?.\['customAction'\]](#parameter-actionscustomaction). +> [!NOTE] +> Used to partially `update` the [current state](#current-state) with a `payload`. +> Affects the following [states](#state): -Typescript Definition: -- `Initial` extends [CTAInitial](#export-type--ctainitial-) +| state | new state | +|----------------------------|-------------------------------------------------------------------------------------------------| +| [current](#statecurrent) | `payload` merged with old [current](#statecurrent) | +| [initial](#stateinitial) | no change | +| [previous](#stateprevious) | old [current](#statecurrent) | +| [changes](#statechanges) | difference between [initial](#stateinitial) and new [current](#statecurrent) or `null` if equal | ---- -##### Return Type: `dispatch.cta?.['customAction']` +### How to `update` a single property -_Optional_ +https://github.com/rafde/react-hook-use-cta/blob/6e82c86f58e637df321b27f116b68d8c514990ec/src/types/UseCTAReturnTypeDispatch.ts#L234-L238 -Custom call to action for changing [state](#return-type-state) +
-Parameters are based on the expected `payload` you defined them in [Parameter: actions?.\['customAction'\]](#parameter-actionscustomaction) + +update a single property example code + ---- +```ts +dispatch.cta.update('search', 'update without option'); +``` -###### Return Type: `dispatch.cta?.['customAction']` with `payload` parameter +
-Example for Return Type: `dispatch.cta?.['customAction']` with `payload` parameter + +update a single property with an option example code + ```ts +dispatch.cta.update('search', 'update with option', {hasOption: true}); +``` -dispatch.cta.addToCount(5); +
-// Alias for -dispatch({ - type: 'addToCount', - payload: 5 -}); +### How to `update` multiple properties -// or -dispatch.cta.addToCount((ctaParam) => { - return ctaParam.previous.count + 10; -}); +https://github.com/rafde/react-hook-use-cta/blob/6e82c86f58e637df321b27f116b68d8c514990ec/src/types/UseCTAReturnTypeDispatch.ts#L228-L233 -// Alias for -dispatch({ - type: 'addToCount', - payload: (ctaParam) => { - return ctaParam.previous.count + 10; - } -}); +
-// or -dispatch.cta.addToCount((ctaParam) => { - // No re-render - return; -}); + +update multiple properties example code + -// Alias for -dispatch({ - type: 'addToCount', - payload: (ctaParam) => { - // No re-render - return; - } +```ts +dispatch.cta.update({ + search: 'dispatch.cta.update', + isFuzzy: true, }); - ```
---- - -###### Return Type: `dispatch.cta?.['customAction']` without parameter -
-Example for dispatch.cta?.['customAction'] without parameter + +update multiple properties with an option example code + ```ts - -dispatch.cta.incrementCount(); - -// Alias for -dispatch({ - type: 'incrementCount', -}); - +dispatch.cta.update( + { + search: 'dispatch.cta.update with options', + isFuzzy: true, + }, + { + updateWithOption: true, + } +); ```
-Effects -- [state](#return-type-state) = `state` change(s) based on [Parameter: actions?.\['customAction'\]](#parameter-actionscustomaction) definition. -- [dispatch.state.current](#return-type-dispatchstatecurrent) = same as [state](#return-type-state) -- [dispatch.state.changes](#return-type-dispatchstatechanges) - - = new differences between [dispatch.state.current](#return-type-dispatchstatecurrent) and [dispatch.state.initial](#return-type-dispatchstateinitial) - - = `null` if no difference. -- [dispatch.state.previous](#return-type-dispatchstateprevious) = previous [dispatch.state.current](#return-type-dispatchstatecurrent) - ---- +
-##### Return Type: `dispatch.cta.update` + +update multiple properties using a callback example code + -Overloaded `function` for partially changing [state](#return-type-state) +```ts +dispatch.cta.update( + /** + * @param {UseCTAReturnTypeDispatchState} ctaState + * @returns {(Initial | void)} returning `void` prevents action from triggering. + */ + (ctaState) => { + if (ctaState.current.count > 10) { + // This is a way to prevent an update from triggering. + return; + } + + return { + search: 'dispatch.cta.update with callback', + count: ctaState.current.count + 1, + } + } +); +``` -https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L196-L197 +
-Typescript Definition: -- `Initial` extends [CTAInitial](#export-type--ctainitial-) -- [UseCTAReturnTypeDispatchState](#export-type--usectareturntypedispatchstate-) +
---- + +update multiple properties with an option using a callback example code + -###### Return Type: `dispatch.cta.update` with `payload` parameter +```ts +dispatch.cta.update( + /** + * @param {UseCTAReturnTypeDispatchState} ctaState + * @returns {(Initial | void)} returning `void` prevents action from triggering. + */ + (ctaState) => { + if (ctaState.current.count > 10) { + // This is a way to prevent an update from triggering. + return; + } -Accepts partial key/values from [Initial](#parameter-initial) and updates [state](#return-type-state) with partial change(s) + return { + search: 'dispatch.cta.update with callback and options', + count: ctaState.current.count + 1, + } + }, + { + updateWithCallbackOption: true, + } +); +``` -https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L196 +
-Example + +Using dispatcher function instead of dispatch.cta.update + -```ts +https://github.com/rafde/react-hook-use-cta/blob/6e82c86f58e637df321b27f116b68d8c514990ec/src/types/UseCTAReturnTypeDispatch.ts#L34-L40 -dispatch.cta.update({ - // partial `state` change - search: 'update', - count: 8, +```ts +dispatch({ + type: 'update', + payload: { + search: 'dispatch update', + isFuzzy: true, + }, }); -// Alias for dispatch({ type: 'update', payload: { - // partial `state` change - search: 'update', - count: 8, + search: 'dispatch update with options', + isFuzzy: true, + }, + options: { + dispatchUpdateWithOption: true, } }); -// or -dispatch.cta.update((ctaParam) => { - return { - // partial `state` change - search: 'update', - count: 8, - }; -}); - -// Alias for dispatch({ type: 'update', - payload: (ctaParam) => { + payload(ctaState) { + if (ctaState.current.count > 10) { + // This is a way to prevent an update from happening. + return; + } + return { - // partial `state` change - search: 'update', - count: 8, - }; - } + search: 'dispatch.cta.update with callback', + count: ctaState.current.count + 1, + } + }, }); -// or -dispatch.cta.update((ctaParam) => { - // No re-render - return; -}); -// Alias for dispatch({ type: 'update', - payload: (ctaParam) => { - // No re-render - return; + payload: (ctaState) => ({ + search: 'dispatch update with callback and options', + count: ctaState.current.count + 1, + }), + options: { + dispatchUpdateWithCallbackAndOption: true, } }); - ```
---- - -###### Return Type: `dispatch.cta.update` with `key` and `value` parameters +### How to augment `update` -https://github.com/rafde/react-hook-use-cta/blob/1e97f6ef6c5bc3d053cf64007bfea7c5c84877a0/src/types/UseCTAReturnTypeDispatch.ts#L197 +https://github.com/rafde/react-hook-use-cta/blob/6e82c86f58e637df321b27f116b68d8c514990ec/src/types/UseCTAParameterActionsPredefinedRecord.ts#L8 -Accepts a key from [Initial](#parameter-initial) and a corresponding value type for that key from [Initial](#parameter-initial)`[keyof Initial]` -and updates [state](#return-type-state) with partial change +
+ +augment update example code + -
+```tsx +import {useEffect} from 'react'; +import {useCTA, CTAStateParam,} from 'react-hook-use-cta' -Example +const initial = { + search: 'initial', + isFuzzy: false, + count: 0, +} -```ts +function View() { + const [ + state, + dispatch, + ] = useCTA({ + initial, + actions: { + /** + * @param {CTAStateParam} ctaStateParam + * @param {typeof initial} payload + * @returns {(Partial | void)} returning `void` prevents action from triggering. + */ + update(ctaStateParam, payload,) { + const { + current, + options, + } = ctaStateParam; + let { + count, + } = payload; + + if (!Number.isSafeInteger(count)) { + // if `count` is not a safe integer, prevent update + return; + } -dispatch.cta.update('seatch', 'update'); // partial `state` change + // set count to current.count if allowNegativeCount is falsey and count is less than 0 + if (count < 0 && !options?.allowNegativeCount) { + count = current.count; + } -// Alias for -dispatch.cta.update({ - seatch: 'update', -}); + return { + ...payload, + count + }; + } + } + }); -``` + useEffect( + () => { + dispatch.cta.update( + 'count', + -1, + { + allowNegativeCount: true + } + ); + }, + [ + dispatch, + ] + ); + + // will render `-1` + return state.count; +} +```
-Effects -- [state](#return-type-state) = new `state` with partial change(s). -- [dispatch.state.current](#return-type-dispatchstatecurrent) = new `state` with partial change(s). -- [dispatch.state.changes](#return-type-dispatchstatechanges) - - = new differences between [dispatch.state.current](#return-type-dispatchstatecurrent) and [dispatch.state.initial](#return-type-dispatchstateinitial) - - = `null` if no difference. -- [dispatch.state.previous](#return-type-dispatchstateprevious) = previous [dispatch.state.current](#return-type-dispatchstatecurrent) +## `replace` ---- +> [!NOTE] +> Used to `replace` [current state](#current-state) with a `payload`. +> Affects the following [states](#state): + +| state | new state | +|----------------------------|-------------------------------------------------------------------------------------------------| +| [current](#statecurrent) | `payload` | +| [initial](#stateinitial) | no change | +| [previous](#stateprevious) | old [current](#statecurrent) | +| [changes](#statechanges) | difference between [initial](#stateinitial) and new [current](#statecurrent) or `null` if equal | -##### Return Type: `dispatch.cta.replace` +### How to `replace` the entire state -Replace entire [state](#return-type-state) with a new `state`. +https://github.com/rafde/react-hook-use-cta/blob/6e82c86f58e637df321b27f116b68d8c514990ec/src/types/UseCTAReturnTypeDispatch.ts#L210-L215 -https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L193 +
-Typescript Definition: -- `Initial` extends [CTAInitial](#export-type--ctainitial-) -- [UseCTAReturnTypeDispatchState](#export-type--usectareturntypedispatchstate-) + +replace entire state example code + + +```ts +dispatch.cta.replace({ + search: 'dispatch.cta.replace', + isFuzzy: true, + count: 10, +}); +``` + +
-Example for Return Type: dispatch.cta.replace + +replace entire state with an option example code + ```ts +dispatch.cta.replace( + { + search: 'dispatch.cta.replace with options', + isFuzzy: true, + count: 10, + }, + { + isReplacingWithOption: true, + } +); -dispatch.cta.replace({ - // new `state` - search: 'replace', - isFuzzy: false, - count: 8, -}); +``` + +
+ +
+ + +replace entire state using a callback example code + + +```ts -// Alias for +dispatch.cta.replace( + /** + * @param {UseCTAReturnTypeDispatchState} ctaState + * @returns {(Initial | void)} returning `void` prevents triggering the action + */ + (ctaState) => { + const count = ctaState.current.count; + // This is a way to prevent replace from happening. + if (count > 10) { + return; + } + return { + search: 'dispatch.cta.replace with callback', + isFuzzy: true, + count, + } + } +); +``` + +
+ +
+ + +replace entire state with an option using a callback example code + + +```ts +dispatch.cta.replace( + /** + * @param {UseCTAReturnTypeDispatchState} ctaState + * @returns {(Initial | void)} returning `void` prevents triggering the action + */ + (ctaState) => ({ + search: 'dispatch.cta.replace with callback and options', + isFuzzy: true, + count: ctaState.current.count + 1, + }), + { + isCallbackReplacingWithOption: true, + } +); +``` + +
+ +
+ + +Using dispatcher function instead of dispatch.cta.replace + + + +https://github.com/rafde/react-hook-use-cta/blob/6e82c86f58e637df321b27f116b68d8c514990ec/src/types/UseCTAReturnTypeDispatch.ts#L10-L16 + +```ts dispatch({ type: 'replace', payload: { - // new `state` - search: 'replace', - isFuzzy: false, - count: 8, + search: 'dispatch replace', + isFuzzy: true, + count: 10, } }); -// or -dispatch.cta.replace((ctaParam) => { - return { - // new `state` - search: 'replace', - isFuzzy: false, - count: 8, - }; -}); - -// Alias for dispatch({ type: 'replace', - payload: (ctaParam) => { - return { - // new `state` - search: 'replace', - isFuzzy: false, - count: 8, - }; + payload: { + search: 'dispatch replace with option', + isFuzzy: true, + count: 10, + }, + options: { + isReplacingWithOption: true, } }); -// or -dispatch.cta.replace((ctaParam) => { - // No re-render - return; +dispatch({ + type: 'replace', + /** + * @param {UseCTAReturnTypeDispatchState} ctaState + * @returns {(Initial | void)} returning `void` prevents action from triggering. + */ + payload: (ctaState) => { + const count = ctaState.current.count; + + if (count > 10) { + // This is a way to prevent replace from triggering. + return; + } + + return { + search: 'dispatch.cta.replace with callback', + isFuzzy: true, + count, + } + }, }); -// Alias for dispatch({ type: 'replace', - payload: (ctaParam) => { - // No re-render - return; + /** + * @param {UseCTAReturnTypeDispatchState} ctaState + * @returns {(Initial | void)} returning `void` prevents action from triggering. + */ + payload: (ctaState) => { + const count = ctaState.current.count; + + if (count > 10) { + // This is a way to prevent replace from triggering. + return; + } + + return { + search: 'dispatch.cta.replace with callback with options', + isFuzzy: true, + count, + } + }, + options: { + isCallbackReplacingWithOption: true, } }); ```
-Effects -- [state](#return-type-state) = new `state` -- [dispatch.state.current](#return-type-dispatchstatecurrent) = new `state` -- [dispatch.state.changes](#return-type-dispatchstatechanges) - - = new differences between [dispatch.state.current](#return-type-dispatchstatecurrent) and [dispatch.state.initial](#return-type-dispatchstateinitial) - - = `null` if no difference. -- [dispatch.state.previous](#return-type-dispatchstateprevious) = previous [dispatch.state.current](#return-type-dispatchstatecurrent) +### How to augment `replace` ---- +https://github.com/rafde/react-hook-use-cta/blob/6e82c86f58e637df321b27f116b68d8c514990ec/src/types/UseCTAParameterActionsPredefinedRecord.ts#L5 -##### Return Type: `dispatch.cta.replaceInitial` +
-Replace entire [dispatch.state.initial](#return-type-dispatchstateinitial) value with a new `initial` value. +augment replace example code -https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L194 +```tsx +import {useEffect} from 'react'; +import {useCTA, CTAStateParam,} from 'react-hook-use-cta' -Typescript Definition: -- `Initial` extends [CTAInitial](#export-type--ctainitial-) -- [UseCTAReturnTypeDispatchState](#export-type--usectareturntypedispatchstate-) +const initial = { + search: 'initial', + isFuzzy: false, + count: 0, +} -
+function View() { + const [ + state, + dispatch, + ] = useCTA({ + initial, + actions: { + /** + * @param {CTAStateParam} ctaStateParam + * @param {typeof initial} payload + * @return {(typeof initial | void)} returning `void` prevents action from triggering. + */ + replace(ctaStateParam, payload,) { + const { + current, + options, + } = ctaStateParam; + let { + count, + } = payload; + + if (Number.isSafeInteger(count)) { + // if count is not a safe integer, prevent triggering replace + return; + } + + // set count to current.count if allowNegativeCount is falsey and count is less than 0 + if (count < 0 && !options?.allowNegativeCount) { + count = current.count; + } -Example for Return Type: dispatch.cta.replaceInitial + return { + ...payload, + count + }; + } + } + }); -```ts + useEffect( + () => { + dispatch.cta.replace( + { + search: 'replace', + isFuzzy: true, + count: 10, + }, + { + allowNegativeCount: true, + } + ); + }, + [ + dispatch, + ] + ); + + // will render `-1` + return state.count; +} +``` + +
+ +## `replaceInitial` + +> [!NOTE] +> Set a new [initial](#stateinitial) state with a `payload`. The idea of this action is in case there +> is new source data that should be used to compare changes with [current state](#current-state) +> Affects the following [states](#state): + +| state | new state | +|----------------------------|-------------------------------------------------------------------------------------------------| +| [current](#statecurrent) | no change | +| [initial](#stateinitial) | `payload` | +| [previous](#stateprevious) | no change | +| [changes](#statechanges) | difference between [initial](#stateinitial) and new [current](#statecurrent) or `null` if equal | +### How to call `replaceInitial` + +https://github.com/rafde/react-hook-use-cta/blob/6e82c86f58e637df321b27f116b68d8c514990ec/src/types/UseCTAReturnTypeDispatch.ts#L216-L221 + +
+ + +replaceInitial state example code + + +```ts dispatch.cta.replaceInitial({ - // new `initial` - search: 'replaceInitial', + search: 'dispatch.cta.replaceInitial', isFuzzy: true, - count: 5, + count: 10, }); +``` -// Alias for +
+ +
+ + +replaceInitial state using an option example code + + +```ts +dispatch.cta.replaceInitial( + { + search: 'dispatch.cta.replaceInitial with option', + isFuzzy: true, + count: 10, + }, + { + isReplaceInitialWithOption: true, + } +); +``` + +
+ +
+ + +replaceInitial state using a callback example code + + +```ts +dispatch.cta.replaceInitial( + /** + * @param {UseCTAReturnTypeDispatchState} ctaState + * @returns {(Initial | void)} returning `void` prevents action from triggering. + */ + (ctaState) => { + if (ctaState.current.count > 10) { + // This is a way to prevent replaceInitial from triggering. + return; + } + + return { + search: 'dispatch.cta.replaceInitial with callback', + isFuzzy: true, + count: ctaState.current.count, + } + } +); +``` + +
+ +
+ + +replaceInitial state with option using a callback example code + + +```ts +dispatch.cta.replaceInitial( + /** + * @param {UseCTAReturnTypeDispatchState} ctaState + * @returns {(Initial | void)} returning `void` prevents action from triggering. + */ + (ctaState) => { + if (ctaState.current.count > 10) { + // This is a way to prevent replaceInitial from triggering. + return; + } + + return { + search: 'dispatch.cta.replaceInitial with callback with options', + isFuzzy: true, + count: ctaState.current.count, + } + }, + { + isReplaceInitialCallbackWithOption: true, + } +); +``` + +
+ +
+ + +Using dispatcher function instead of dispatch.cta.replaceInitial + + +https://github.com/rafde/react-hook-use-cta/blob/6e82c86f58e637df321b27f116b68d8c514990ec/src/types/UseCTAReturnTypeDispatch.ts#L18-L24 + +```ts dispatch({ type: 'replaceInitial', payload: { - // new `initial` - search: 'replaceInitial', + search: 'dispatch replaceInitial', isFuzzy: true, - count: 5, + count: 10, } }); -// or -dispatch.cta.replaceInitial((ctaParam) => { - return { - // new `initial` - search: 'replaceInitial', +dispatch({ + type: 'replaceInitial', + payload: { + search: 'dispatch replaceInitial with options', isFuzzy: true, - count: 5, - }; + count: 10, + }, + options: { + isReplacingWithOption: true, + } }); -// Alias for dispatch({ type: 'replaceInitial', - payload: (ctaParam) => { + /** + * @param {UseCTAReturnTypeDispatchState} ctaState + * @returns {(Initial | void)} returning `void` prevents action from triggering. + */ + payload(ctaState) { + if (ctaState.current.count > 10) { + // This is a way to prevent replaceInitial from triggering. + return; + } + return { - // new `initial` - search: 'replaceInitial', + search: 'dispatch.cta.replaceInitial with callback', isFuzzy: true, - count: 5, - }; - } -}); - -// or -dispatch.cta.replaceInitial((ctaParam) => { - // No re-render - return; + count: ctaState.current.count, + } + }, }); -// Alias for dispatch({ type: 'replaceInitial', - payload: (ctaParam) => { - // No re-render - return; + /** + * @param {UseCTAReturnTypeDispatchState} ctaState + * @returns {(Initial | void)} returning `void` prevents action from triggering. + */ + payload: (ctaState) => ({ + search: 'dispatch replaceInitial with callback and options', + isFuzzy: true, + count: ctaState.current.count + 1, + }), + options: { + isCallbackReplacingWithOption: true, } }); - ```
-Effects -- [dispatch.state.initial](#return-type-dispatchstateinitial) = new `initial` -- [dispatch.state.changes](#return-type-dispatchstatechanges) - - = new differences between [dispatch.state.current](#return-type-dispatchstatecurrent) and [dispatch.state.initial](#return-type-dispatchstateinitial) - - = `null` if no difference. +### How to augment `replaceInitial` ---- +https://github.com/rafde/react-hook-use-cta/blob/6e82c86f58e637df321b27f116b68d8c514990ec/src/types/UseCTAParameterActionsPredefinedRecord.ts#L6 -##### Return Type: `dispatch.cta.reset` +```tsx +import {useEffect} from 'react'; +import {useCTA, CTAStateParam,} from 'react-hook-use-cta' -Overloaded `function` that differs in behavior when called with payload parameter and without parameter. +const initial = { + search: 'initial', + isFuzzy: false, + count: 0, +} -https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L195 +function View() { + const [ + state, + dispatch, + ] = useCTA({ + initial, + actions: { + /** + * @param {CTAStateParam} ctaStateParam + * @param {typeof initial} payload + * @returns {(typeof initial | void)} returning `void` prevents action from triggering. + */ + replaceInitial(ctaStateParam, payload) { + const { + current, + options, + } = ctaStateParam; + let { + count, + } = payload; -Typescript Definition: -- `Initial` extends [CTAInitial](#export-type--ctainitial-) -- [UseCTAReturnTypeDispatchState](#export-type--usectareturntypedispatchstate-) + if (Number.isSafeInteger(count)) { + // prevent replaceInitial if count is not a safe integer + return; + } ---- + // set count to current.count if allowNegativeCount is falsey and count is less than 0 + if (count < 0 && !options?.allowNegativeCount) { + count = current.count; + } -###### Return Type: `dispatch.cta.reset` without parameter + return { + ...payload, + count + }; + } + } + }); -Sets [state](#return-type-state) equal to [dispatch.state.initial](#return-type-dispatchstateinitial) + useEffect( + () => { + dispatch.cta.replaceInitial( + { + search: 'replaceInitial', + isFuzzy: true, + count: 10, + }, + { + allowNegativeCount: true, + } + ); + }, + [ + dispatch, + ] + ); + + // will render `10` + return dispatch.state.initial.count; +} +``` -
+## `reset` + +> [!NOTE] +> `reset` is a special action that has 2 behaviors: + +### How to call `reset` without a `payload` to replace `current` state with `initial` state + +https://github.com/rafde/react-hook-use-cta/blob/6e82c86f58e637df321b27f116b68d8c514990ec/src/types/UseCTAReturnTypeDispatch.ts#L222-L227 -Example for Return Type: dispatch.cta.reset without parameter +> [!NOTE] +> If no `payload` is sent, then the `current` state will be replaced the `initial` state. +> Affects the following [states](#state): + +| state | new state | +|----------------------------|------------------------------| +| [current](#statecurrent) | [initial](#stateinitial) | +| [initial](#stateinitial) | no change | +| [previous](#stateprevious) | old [current](#statecurrent) | +| [changes](#statechanges) | `null` | + +
+ +reset state example code ```ts +// sets current state = to initial state dispatch.cta.reset(); +``` + +
+ +
+ + +reset state example code using an option + + +```ts +// sets current state = to initial state +dispatch.cta.reset( + undefined, + { + resetWithOption: true, + } +); +``` + +
+ +
+ + +Using dispatcher function instead of dispatch.cta.reset without payload + + +https://github.com/rafde/react-hook-use-cta/blob/6e82c86f58e637df321b27f116b68d8c514990ec/src/types/UseCTAReturnTypeDispatch.ts#L26-L32 + +```tsx +dispatch({ + type: 'reset' +}); -// Alias for dispatch({ type: 'reset', + options: { + resetWithOption: true, + } }); + ```
-Effects -- [state](#return-type-state) = [dispatch.state.initial](#return-type-dispatchstateinitial) -- [dispatch.state.current](#return-type-dispatchstatecurrent) = [dispatch.state.initial](#return-type-dispatchstateinitial) -- [dispatch.state.changes](#return-type-dispatchstatechanges) = `null` -- [dispatch.state.previous](#return-type-dispatchstateprevious) = previous [dispatch.state.current](#return-type-dispatchstatecurrent) +### How to call `reset` with payload ---- +> [!NOTE] +> If a `payload` is sent, then the `initial` state and the `current` state will be replaced with the `payload`. +> Affects the following [states](#state): -###### Return Type: `dispatch.cta.reset` with `payload` parameter +| state | new state | +|----------------------------|------------------------------| +| [current](#statecurrent) | `payload` | +| [initial](#stateinitial) | `payload` | +| [previous](#stateprevious) | old [current](#statecurrent) | +| [changes](#statechanges) | `null` | -Sets [state](#return-type-state) and [dispatch.state.initial](#return-type-dispatchstateinitial) equal to `payload` -
+
-Example for Return Type: dispatch.cta.reset with payload parameter + +reset state with payload example code + ```ts - +// sets current state and initial state equal to payload dispatch.cta.reset({ - // new `state` and `initial` - search: 'reset', + search: 'dispatch.cta.reset', isFuzzy: true, count: 10, }); +``` -// Alias for +
+ +
+ + +reset state with payload and option example code + + +```ts +// sets current state and initial state equal to payload +dispatch.cta.reset( + { + search: 'dispatch.cta.reset with options', + isFuzzy: true, + count: 10, + }, + { + resetInitialWithOption: true, + } +); +``` + +
+ +
+ + +reset state with payload as callback example code + + +```ts +// sets current state and initial state equal to payload +dispatch.cta.reset( + /** + * @param {UseCTAReturnTypeDispatchState} ctaState + * @returns {(Initial | void)} returning `void` prevents action from triggering. + */ + (ctaState) => { + if (ctaState.current.count > 10) { + // prevent reset from triggering + return; + } + + // sets current state and initial state equal to payload + return { + search: 'dispatch.cta.reset with callback', + isFuzzy: true, + count: ctaState.current.count, + } + } +); +``` + +
+ +
+ + +reset state with payload as callback and option example code + + +```ts +// sets current state and initial state equal to payload +dispatch.cta.reset( + /** + * @param {UseCTAReturnTypeDispatchState} ctaState + * @returns {(Initial | void)} returning `void` prevents action from triggering. + */ + (ctaState) => { + if (ctaState.current.count > 10) { + // prevent reset from triggering + return; + } + + return { + search: 'dispatch.cta.reset with callback with options', + isFuzzy: true, + count: ctaState.current.count + 1, + } + }, + { + resetCallbackWithOption: true, + } +); +``` + +
+ +
+ + +Using dispatcher function instead of dispatch.cta.reset with payload + + +```ts dispatch({ type: 'reset', payload: { - // new `state` and `initial` - search: 'reset', + search: 'dispatch reset', isFuzzy: true, count: 10, } }); -// or -dispatch.cta.reset((ctaParam) => { - return { - // new `state` and `initial` - search: 'reset', +dispatch({ + type: 'reset', + payload: { + search: 'dispatch reset with option', isFuzzy: true, count: 10, - }; + }, + options: { + resetInitialWithOption: true, + } }); -// Alias for dispatch({ type: 'reset', - payload: (ctaParam) => { + /** + * @param {UseCTAReturnTypeDispatchState} ctaState + * @returns {(Initial | void)} returning `void` prevents action from triggering. + */ + payload(ctaState) { + if (ctaState.current.count > 10) { + // prevent reset from triggering + return; + } + + // sets current state and initial state equal to payload return { - // new `state` and `initial` - search: 'reset', + search: 'dispatch.cta.reset with callback', isFuzzy: true, - count: 10, - }; - } -}); - -// or -dispatch.cta.reset((ctaParam) => { - // No re-render - return; + count: ctaState.current.count, + } + }, }); -// Alias for dispatch({ type: 'reset', - payload: (ctaParam) => { - // No re-render - return; + /** + * @param {UseCTAReturnTypeDispatchState} ctaState + * @returns {(Initial | void)} returning `void` prevents action from triggering. + */ + payload: (ctaState) => (ctaState) => { + if (ctaState.current.count > 10) { + // prevent reset from triggering + return; + } + + return { + search: 'dispatch.cta.reset with callback', + isFuzzy: true, + count: ctaState.current.count + 1, + } + }, + options: { + resetCallbackWithOption: true, } }); ```
-Effects -- [state](#return-type-state) = new `state` -- [dispatch.state.current](#return-type-dispatchstatecurrent) = new `state` -- [dispatch.state.changes](#return-type-dispatchstatechanges) = `null` -- [dispatch.state.initial](#return-type-dispatchstateinitial) = new `state` -- [dispatch.state.previous](#return-type-dispatchstateprevious) = previous [dispatch.state.current](#return-type-dispatchstatecurrent) +### How to augment `reset` ---- +https://github.com/rafde/react-hook-use-cta/blob/6e82c86f58e637df321b27f116b68d8c514990ec/src/types/UseCTAParameterActionsPredefinedRecord.ts#L7 -#### Return Type: `dispatch.state` +
-https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L224 +augment reset example code -Is of type `UseCTAReturnTypeDispatchState`. +```ts +import {useEffect} from 'react'; +import {useCTA, CTAStateParam,} from 'react-hook-use-cta' -https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L212-L217 +const initial = { + search: 'initial', + isFuzzy: false, + count: 0, +} -This is extra data information that can be referenced for certain changes over time. +function View() { + const [ + state, + dispatch, + ] = useCTA({ + initial, + actions: { + /** + * @param {CTAStateParam} ctaStateParam + * @param {typeof initial=} payload - optional + * @returns {(typeof initial | void)} returning `void` prevents action from triggering. + */ + reset(ctaStateParam, payload,) { + const { + current, + options, + } = ctaStateParam; + + if (!payload) { + // this will set current = initial + return ctaStateParam.initial; + } + + let { + count, + } = payload; + + if (!Number.isSafeInteger(count)) { + // prevent reset from triggering + return; + } + + // set count to current.count if allowNegativeCount is falsey and count is less than 0 + if (count < 0 && !options?.allowNegativeCount) { + count = current.count; + } -Typescript Definition: -- [CTAInitial](#export-type--ctainitial-) + return { + ...payload, + count, + }; + } + } + }); ---- + useEffect( + () => { + dispatch.cta.reset( + { + search: 'replace', + isFuzzy: true, + count: -1, + }, + { + allowNegativeCount: true, + } + ); + }, + [ + dispatch, + ] + ); + + // will render `-1` + return state.count; +} +``` -##### Return Type: `dispatch.state.current` +
-https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L214 +## Custom Actions -The value is equal to [Return Type: state](#return-type-dispatchstate) +> [!NOTE] +> When the available actions aren't enough, you can define your own specialized custom actions using action behaviors. -Typescript Definition: -- `Initial` extends [CTAInitial](#export-type--ctainitial-) +TBD: provide TS snippet ---- +> [!IMPORTANT] +> All custom action callbacks receive a [CustomCTAStateParam](#export-type--customctastateparam-) as their first parameter. +> The second parameter depends on what you want sent as a `payload` -##### Return Type: `dispatch.state.initial` +### How to define and call custom action as `update` behavior -https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L215 +
-Starts of equal to [initial](#parameter-initial) or the result of [onInit](#parameter-oninit). + +Defining custom update action + -It can be changed with [dispatch.cta.replaceInitial](#return-type-dispatchctareplaceinitial) -or [dispatch.cta.reset with payload parameter](#return-type-dispatchctareset-with-payload-parameter) +```tsx -Typescript Definition: -- `Initial` extends [CTAInitial](#export-type--ctainitial-) +``` ---- +
-##### Return Type: `dispatch.state.changes` +
-https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L213 + +Defining custom update action using updateAction behavior + -- `Partial`: When key/values of [dispatch.state.current](#return-type-dispatchstatecurrent) are not equal to - [dispatch.state.initial](#return-type-dispatchstateinitial) Example: - ```ts - dispatch.state.initial /* = { - search: '', - isFuzzy: true, - count: 1, - } */ - - dispatch.state.current /* = { - search: 'current', - isFuzzy: true, - count: 1, - } */ - - dispatch.state.changes /* = { - search: 'current', - } */ - - if ( dispatch.state.changes ) { - console.log('state has changes') - } - ``` -- `null`: When the key/values [dispatch.state.initial](#return-type-dispatchstateinitial) - and [dispatch.state.current](#return-type-dispatchstatecurrent) are equal. Example: - ```ts - dispatch.state.initial /* = { - search: 'current', - isFuzzy: true, - count: 1, - } */ - - dispatch.state.current /* = { - search: 'current', - isFuzzy: true, - count: 1, - } */ - - dispatch.state.changes /* = null */ - - if ( !dispatch.state.changes ) { - console.log('No changes to state') - } - ``` - -Typescript Definition: -- `Initial` extends [CTAInitial](#export-type--ctainitial-) +```tsx ---- +``` -##### Return Type: `dispatch.state.previous` +
-https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L216 +
-Equal to the previous [dispatch.state.current](#return-type-dispatchstatecurrent) value. + +Calling custom update action + -Typescript Definition: -- `Initial` extends [CTAInitial](#export-type--ctainitial-) +
---- +### How to define and call custom action as `replace` behavior -## Typescript `export`s +
-https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/index.ts#L22-L32 + +Defining custom replace action using replaceAction + ---- +```tsx -## `export type { CTAInitial, }` +``` -https://github.com/rafde/react-hook-use-cta/blob/9e9206f1ff06e2de5adcde5d107d9d847e210063/src/types/CTAInitial.ts#L1 +
---- +
-## `export type { CustomCTAParam, }` + +Calling custom replace action + -https://github.com/rafde/react-hook-use-cta/blob/adfd2a0448f08a4d1374db0136f77dde9c64da7a/src/types/CustomCTAParam.ts#L11-L16 +```tsx ---- +``` -## `export type { UseCTAParameter, }` +
+ +### How to define and call custom action as `replaceInitial` behavior + +
+ + +Defining custom replaceInitial action using replaceInitialAction + + +```tsx + +``` + +
+ +
+ + +Calling custom replaceInitial action + + +```tsx + +``` + +
+ +### How to define and call custom action as `reset` behavior + +
+ + +Defining custom reset action using resetAction + + +```tsx + +``` + +
+ +
+ + +Calling custom reset action + + +```tsx + +``` -See [Parameter](#parameter) +
--- -## `export type { UseCTAReturnTypeDispatchState, }` +# createCTAContext -See [Return Type: dispatch](#return-type-dispatch) +> [!NOTE] +> Combines state and actions of `useCTA` with React `createContext` and `useContext`. +> Accepts the same parameters as `useCTA` and returns an `object` with key/values. -## `export type { UseCTAReturnTypeDispatch, }` +
+ +Create a file for exporting, example globalContext.ts + +```tsx +import { createCTAContext, } from 'react-hook-use-cta' + +export const GlobalContext = createCTAContext({ + initial: { + search: 'initial', + isFuzzy: false, + count: 0, + }, +}); +``` + +
+ +## CTAProvider + +> [!NOTE] +> Provider to wrap the app or component for context. + +
+ + + CTAProvider example code + + +```tsx +import GlobalContext from './globalContext'; +import { GlobalCountView, } from './GlobalCountView' +import { GlobalCountButton, } from './GlobalCountButton' + +export function App() { + return + + + ; +} +``` + +
+ +## useCTAStateContext -See [Return Type: dispatch](#return-type-dispatch) +> [!NOTE] +> Hook that returns the current state + +
+ + +useCTAStateContext example code + + +```tsx +import { GlobalContext, } from './globalContext'; + +const { + useCTAStateContext +} = GlobalContext; + +export function GlobalCountView() { + const globalState = useCTAStateContext(); + return
+ {globalState.count} +
; +} +``` + +
+ +## useCTADispatchContext + +> [!NOTE] +> Hook that returns cta dispatch. Returns `null` if called outside [CTAProvider](#ctaprovider) + +
+ + +useCTADispatchContext example code + + +```tsx +import { useCallback, } from 'react'; +const { + useCTADispatchContext +} = GlobalContext; + +export function GlobalCountButton() { + const globalDispatch = useCTADispatchContext(); + const onClick = useCallback( + () => { + globalDispatch.cta.update((state) => { + return { + count: state.current.count + 1, + } + }) + }, + [ + globalDispatch + ] + ) + return ; +} +``` + +
--- +# returnActionsType + +https://github.com/rafde/react-hook-use-cta/blob/f54b6883985cfc2399c8d2a69329f903ca737009/src/index.ts#L36-L41 + +> [!NOTE] +> In case you need to define [actions](#actions) parameter from a variable, this function can help infer [actions](#actions) type + +
+ +returnActionsType example code + +```ts +import { returnActionsType, } from 'react-hook-use-cta'; + +const initial = { + search: 'initial', + isFuzzy: false, + count: 0, +}; +const actions = returnActionsType( + initial, + { + setSearch(state, search: string) { + return { + search + } + } + } +); + +``` + +
+ +--- + +# Typescript `export`s + +https://github.com/rafde/react-hook-use-cta/blob/6e82c86f58e637df321b27f116b68d8c514990ec/src/index.ts#L24-L36 + +## `export type { CTAInitial, }` + +https://github.com/rafde/react-hook-use-cta/blob/9e9206f1ff06e2de5adcde5d107d9d847e210063/src/types/CTAInitial.ts#L1 + +## `export type { UseCTAParameter, }` + +https://github.com/rafde/react-hook-use-cta/blob/6c8def7fcd104b6ae0d25627eaad1a1e35a3a391/src/types/UseCTAParameter.ts#L4-L19 + ## `export type { UseCTAReturnType, }` -See [Return Type](#return-type) +https://github.com/rafde/react-hook-use-cta/blob/65c3b53dd5d51812e3ffc111ba23c4bc84f614ee/src/types/UseCTAReturnType.ts#L4-L10 ---- +## `export type { UseCTAReturnTypeDispatch, }` +https://github.com/rafde/react-hook-use-cta/blob/65c3b53dd5d51812e3ffc111ba23c4bc84f614ee/src/types/UseCTAReturnTypeDispatch.ts#L261-L267 +## `export type { CustomCTAStateParam, }` + +https://github.com/rafde/react-hook-use-cta/blob/6e82c86f58e637df321b27f116b68d8c514990ec/src/types/CustomCTAStateParam.ts#L11-L21 + +## `export type { CTAStateParam, }` + +https://github.com/rafde/react-hook-use-cta/blob/6c8def7fcd104b6ae0d25627eaad1a1e35a3a391/src/types/CTAStateParam.ts#L4-L9 + +## `export type { CustomCTAReturnType, }` + +https://github.com/rafde/react-hook-use-cta/blob/6c8def7fcd104b6ae0d25627eaad1a1e35a3a391/src/types/CustomCTAReturnType.ts#L4-L9 + +--- diff --git a/README_OLD.md b/README_OLD.md new file mode 100644 index 0000000..6ecbd76 --- /dev/null +++ b/README_OLD.md @@ -0,0 +1,1258 @@ +# react-hook-use-cta: useCTA (use Call To Action) + +A somewhat flexible react hook alternative to `React.useReducer`. Written in Typescript. + +[Demo Playground](https://codesandbox.io/p/sandbox/react-hook-use-cta-7jnc32?file=%2Fsrc%2FApp.tsx) + +## Table of Contents + +- [Installation](#installation) + - [NPM](#npm) +- [export { useCTA }](#export--usecta-) + - [Usage](#usage) + +
+ +Table of Contents: Parameter + +- [Parameter](#parameter) + - [initial](#parameter-initial) + - [onInit](#parameter-oninit) + - [actions](#parameter-actions) + - [Predefined actions](#predefine-actions) + - [actions?.\['customAction'\]](#parameter-actionscustomaction) + - [Parameter](#parameter-actionscustomaction) + 1. [1st Parameter: CustomCTAParam](#actionscustomaction-1st-parameter-customctaparam) + - [replaceAction](#actionscustomaction-1st-parameter-customctaparamreplaceaction) + - [replaceInitialAction](#actionscustomaction-1st-parameter-customctaparamreplaceinitialaction) + - [resetAction](#actionscustomaction-1st-parameter-customctaparamresetaction) + - [updateAction](#actionscustomaction-1st-parameter-customctaparamupdateaction) + 2. [2nd Parameter: payload](#actionscustomaction-2nd-parameter-payload) + - [Return Type](#actionscustomaction-return-type) + +
+ +
+ +Table of Contents: Return Type + +- [Return Type](#return-type) + 1. [state](#return-type-state) + 2. [dispatch](#return-type-dispatch) + - [dispatch.cta](#return-type-dispatchcta) + - [dispatch.cta?.\['customAction'\]](#return-type-dispatchctacustomaction) + - [dispatch.cta?.\['customAction'\] with `payload` parameter](#return-type-dispatchctacustomaction-with-payload-parameter) + - [dispatch.cta?.\['customAction'\] without parameter](#return-type-dispatchctacustomaction-without-parameter) + - [dispatch.cta.update](#return-type-dispatchctaupdate) + - [dispatch.cta.update with `payload` parameter](#return-type-dispatchctaupdate-with-payload-parameter) + - [dispatch.cta.update with `key` and `value` parameters](#return-type-dispatchctaupdate-with-key-and-value-parameters) + - [dispatch.cta.replace](#return-type-dispatchctareplace) + - [dispatch.cta.replaceInitial](#return-type-dispatchctareplaceinitial) + - [dispatch.cta.reset](#return-type-dispatchctareset) + - [dispatch.cta.reset without parameter](#return-type-dispatchctareset-with-payload-parameter) + - [dispatch.cta.reset with `payload` parameter](#return-type-dispatchctareset-without-parameter) + - [dispatch.state](#return-type-state) + - [dispatch.state.current](#return-type-dispatchstatecurrent) + - [dispatch.state.initial](#return-type-dispatchstateinitial) + - [dispatch.state.changes](#return-type-dispatchstatechanges) + - [dispatch.state.previous](#return-type-dispatchstateprevious) + +
+ +
+ +Table of Contents: Typescript exports + +- [Typescript exports](#typescript-exports) + - [export type { CTAInitial, }](#export-type--ctainitial-) + - [export type { UseCTAParameter, }](#export-type--usectaparameter-) + - [export type { UseCTAReturnType, }](#export-type--usectareturntype-) + - [export type { UseCTAReturnTypeDispatch, }](#export-type--usectareturntypedispatch-) + - [export type { UseCTAReturnTypeDispatchState, }](#export-type--usectareturntypedispatchstate-) + +
+ + +--- + +## Installation + +``` +react-hook-use-cta fast-equals +``` + +### NPM + +```bash +npm i react-hook-use-cta fast-equals +``` + +--- + +## `export { useCTA }` + +https://github.com/rafde/react-hook-use-cta/blob/9e9206f1ff06e2de5adcde5d107d9d847e210063/src/index.ts#L9-L14 + +### Usage + +```tsx +import { useEffect, } from 'react'; +import { useCTA, } from 'react-hook-use-cta' + +function View() { + const [ + state, + dispatch, + ] = useCTA({ + initial: { + search: 'initial', + isFuzzy: false, + count: 0, + } + }); + + useEffect( + () => dispatch.cta.update('search', 'update'), + [] + ); + + /* Renders `update` */ + return <>{state.search} +} +``` + +
+ +Example using all useCTA parameters + +```tsx +import { useEffect, } from "react"; +import { useCTA, } from 'react-hook-use-cta' + +function View(props: { initial: { search: string, isFuzzy: boolean, count: 0 } }) { + const [ + state, + dispatch, + ] = useCTA({ + initial: props.initial, + onInit(initial) { + return { + ...initial, + search: 'onInit', + } + }, + actions: { + // START: augment predefined actions + replace(ctaParam, payload) { + return payload; + }, + replaceInitial(ctaParam, payload) { + return payload; + }, + reset(ctaParam, payload) { + return payload; + }, + update(ctaParam, payload) { + return payload; + }, + // END: augment predefined actions + + // START: Custom actions + toggleIsFuzzy(ctaParam, isFuzzy?: boolean) { + if (typeof isFuzzy === 'undefined') { + return { + isFuzzy: !ctaParam.previous.isFuzzy, + } + } + + return { + isFuzzy + } + }, + addToCount(ctaParam, value: number) { + return { + count: ctaParam.previous.count + value, + } + }, + incrementCount(ctaParam) { + return { + count: ctaParam.previous.count + 1, + } + }, + // END: Custom actions + } + }); + + useEffect( + () => dispatch.cta.update('search', 'update'), + [] + ); + + return <> +
{state.search}
+
{dispatch.state.initial.search}
+
{dispatch.state.changes?.search}
+
{dispatch.state.previous.search}
+ +} +``` + +
+ +--- + +## Parameter + +**Required** + +Key/value `object` of type `UseCTAParameter` + +https://github.com/rafde/react-hook-use-cta/blob/9e9206f1ff06e2de5adcde5d107d9d847e210063/src/types/UseCTAParameter.ts#L4-L11 + +Typescript Definition: +- [CTAInitial](#export-type--ctainitial-) + +--- + +### Parameter: `initial` + +**Required** + +https://github.com/rafde/react-hook-use-cta/blob/1e97f6ef6c5bc3d053cf64007bfea7c5c84877a0/src/types/UseCTAParameter.ts#L9 + +Similar to `React.useReducer` `initialArg` parameter, +but it only takes key/value `object` that defines the shape of your [state](#return-type-state). + +Values can be anything that +[strictDeepEqual](https://github.com/planttheidea/fast-equals/tree/v5.0.1?tab=readme-ov-file#strictdeepequal) +from [fast-equals](https://github.com/planttheidea/fast-equals/tree/v5.0.1?tab=readme-ov-file#fast-equals) +supports. + +Typescript Definition: +- `Initial` extends [CTAInitial](#export-type--ctainitial-) + +--- + +### Parameter: `onInit` + +_Optional_ + +https://github.com/rafde/react-hook-use-cta/blob/1e97f6ef6c5bc3d053cf64007bfea7c5c84877a0/src/types/UseCTAParameter.ts#L10 + +Similar to `React.useReducer` `init` parameter. Called on first time render. A `function` that is called to replace [initial](#parameter-initial) value. + +Typescript Definition: +- `Initial` extends [CTAInitial](#export-type--ctainitial-) + +--- + +### Parameter: `actions` + +_Optional_ + +Read once on first time render. Key/value `object` to define the types of actions to implement. + +The following results will **not** trigger re-render for all actions: +- Returning a falsy value. +- Returning a non-`null` `object` that doesn't change the values of [state](#return-type-state) +or [dispatch.state.initial](#return-type-dispatchstateinitial) + +#### Predefine actions + +There are predefined actions that can be augmented with the following signatures: + +https://github.com/rafde/react-hook-use-cta/blob/7532ce5d41502f3fc9a0b0275ba2eaae7c2c16fe/src/types/UseCTAParameterActionsPredefinedRecord.ts#L4-L9 + +Augmenting these actions will affect custom actions. + +Typescript Definition: +- [CTAInitial](#export-type--ctainitial-) +- [UseCTAReturnTypeDispatchState](#export-type--usectareturntypedispatchstate-) + +Predefined calls to action: + +- [dispatch.cta.update](#return-type-dispatchctaupdate) +- [dispatch.cta.replace](#return-type-dispatchctareplace) +- [dispatch.cta.replaceInitial](#return-type-dispatchctareplaceInitial) +- [dispatch.cta.reset](#return-type-dispatchctareset) + +--- + +#### Parameter: `actions?.['customAction']` + +You can define your own custom actions to handle +[payload](#actionscustomaction-2nd-parameter-payload)s to your specifications. + +Typescript signature: + +https://github.com/rafde/react-hook-use-cta/blob/adfd2a0448f08a4d1374db0136f77dde9c64da7a/src/types/UseCTAParameterActionsRecordProp.ts#L6-L14 + +Typescript Definitions: +- [CTAInitial](#export-type--ctainitial-) +- [CustomCTAParam](#export-type--customctaparam-) + +Call to action: + +- [`dispatch.cta?.\['customAction'\]](#return-type-dispatchctacustomaction) + - [dispatch.cta?.\['customAction'\] with payload parameter](#return-type-dispatchctacustomaction-with-payload-parameter) + - [dispatch.cta?.\['customAction'\] without parameter](#return-type-dispatchctacustomaction-without-parameter) + +
+ +Example for Parameter: actions?.['customAction'] + +```tsx +import { useCTA } from 'react-hook-use-cta' + +function View(props: {initial: {search: string, isFuzzy: boolean, count: 0}}) { + const [ + state, + dispatch, + ] = useCTA({ + initial: props.initial, + onInit(initial) { + return { + ...initial, + search: 'onInit', + } + }, + actions: { + // START: Custom actions + toggleIsFuzzy(ctaParam, payload?: boolean) { + if (typeof payload === 'undefined') { + return { + isFuzzy: !ctaParam.previous.isFuzzy, + } + } + + return { + isFuzzy: payload, + } + }, + addToCount(ctaParam, payload: number) { + const count = ctaParam.previous.count + payload; + if (isNaN(count) || count < 0) { + return; + } + return { + count, + } + }, + incrementCount(ctaParam) { + return { + count: ctaParam.previous.count + 1, + } + }, + // END: Custom actions + } + }); + + useEffect( + () => dispatch.cta.addToCount(4), + [] + ); + + return <>{state.count} +} +``` + +
+ +--- + +##### `actions?.['customAction']` 1st Parameter: `CustomCTAParam` + +Custom actions' first parameter: + +https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/types/CustomCTAParam.ts#L11-L16 + +extends [UseCTAReturnTypeDispatchState](#return-type-dispatchstate) +with 4 additional functions that affect the behavior of the action. + +https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/types/CustomCTAParam.ts#L12-L15 + +Accepts `result` and `options` + +https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/internal/ActionTypes.ts#L8 + +If predefined actions were augmented, `{useCustom: false}` will bypass them and use default predefined behavior. + +--- + +###### `actions?.['customAction']` 1st Parameter: `CustomCTAParam.replaceAction` + +https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/types/CustomCTAParam.ts#L12 + +Returns instance of `ReplaceActionType` + +https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/internal/ActionTypes.ts#L26 + +Returning `ReplaceActionType` will produce the same outcome as [dispatch.cta.replace](#return-type-dispatchctareplace) + +
+ +Example for CustomCTAParam.replaceAction + +```ts +const [state, dispatch] = useCTA({ + ///...parameter + actions: { + specialReplace(ctaParam, payload?: boolean) { + if (typeof payload === 'undefined') { + // replace `state` with this new state + return ctaParam.replaceAction({ + ...ctaParam.previous, + isFuzzy: true, + }) + } + + // update state + return { + isFuzzy: payload, + } + }, + }, +}); +``` + +
+ +--- + +###### `actions?.['customAction']` 1st Parameter: `CustomCTAParam.replaceInitialAction` + +https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/types/CustomCTAParam.ts#L13 + +Returns instance of `ReplaceInitialActionType` + +https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/internal/ActionTypes.ts#L43 + +Returning `ReplaceIntialActionType` will produce the same outcome as [dispatch.cta.replaceInitial](#return-type-dispatchctareplaceinitial) + +
+ +Example for CustomCTAParam.replaceInitialAction + +```ts +const [state, dispatch] = useCTA({ + ///...parameter + actions: { + specialReplaceInitial(ctaParam, payload?: boolean) { + if (typeof payload === 'undefined') { + // replace `initial` with this new state + return ctaParam.replaceInitialAction({ + ...ctaParam.previous, + isFuzzy: true, + }) + } + + // update state + return { + isFuzzy: payload, + } + }, + }, +}); +``` + +
+ +--- + +###### `actions?.['customAction']` 1st Parameter: `CustomCTAParam.resetAction` + +https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/types/CustomCTAParam.ts#L14 + +Returns instance of `ResetActionType` + +https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/internal/ActionTypes.ts#L60 + +Returning `ResetActionType` will produce the same outcome as [dispatch.cta.reset with payload parameter](#return-type-dispatchctareset-with-payload-parameter) + +
+ +Example for CustomCTAParam.resetAction + +```ts +const [state, dispatch] = useCTA({ + ///...parameter + actions: { + specialReplaceInitial(ctaParam, payload?: boolean) { + if (typeof payload === 'undefined') { + // replace `initial` and `state` with this new state + return ctaParam.resetAction({ + ...ctaParam.previous, + isFuzzy: true, + }) + } + + // update state + return { + isFuzzy: payload, + } + }, + }, +}); +``` + +
+ +--- + +###### `actions?.['customAction']` 1st Parameter: `CustomCTAParam.updateAction` + +https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/types/CustomCTAParam.ts#L15 + +Returns instance of `UpdateActionType` + +https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/internal/ActionTypes.ts#L77 + +Returning `UpdateActionType` will produce the same outcome as [dispatch.cta.update](#return-type-dispatchctaupdate) + +
+ +Example for CustomCTAParam.updateAction + +```ts +const [state, dispatch] = useCTA({ + ///...parameter + actions: { + specialReplaceInitial(ctaParam, payload?: boolean) { + if (typeof payload === 'undefined') { + // replace `initial` and `state` with this new state + return ctaParam.updateAction({ + isFuzzy: true, + }) + } + + // update state + return ctaParam.previous + }, + }, +}); +``` + +
+ +--- + +##### `actions?.['customAction']` 2nd Parameter: `payload` + +`payload`s can be: +- `undefined` +- _optional_ or **required** where the value can be anything +- [Initial](#parameter-initial) type +- `Partial` type + +--- + +##### `actions?.['customAction']` Return Type + +Return type can be +- Falsy value: to **not** trigger re-render. +- `Partial`: triggers re-render if it changes the values of [state](#return-type-state). +Works the same as [CustomCTAParam.updateAction](#actionscustomaction-1st-parameter-customctaparamupdateaction) +- `ReplaceActionType`: See [CustomCTAParam.replaceAction](#actionscustomaction-1st-parameter-customctaparamreplaceaction) +- `ReplaceInitialActionType`: See [CustomCTAParam.replaceInitialAction](#actionscustomaction-1st-parameter-customctaparamreplaceinitialaction) +- `ResetActionType`: See [CustomCTAParam.resetAction](#actionscustomaction-1st-parameter-customctaparamresetaction) +- `UpdateActionType`: See [CustomCTAParam.updateAction](#actionscustomaction-1st-parameter-customctaparamupdateaction) + +--- + +## Return Type + +Array with two values: `[state, dispatch]` of type `UseCTAReturnType` + +https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/types/UseCTAReturnType.ts#L4-L10 + +Typescript Definitions: +- [CTAInitial](#export-type--ctainitial-) +- [UseCTAReturnTypeDispatch](#return-type-dispatch) + +--- +### Return Type: `state` + +Key/value `object` of type [CTAInitial](#export-type--ctainitial-) + +The current `state`. During the first render, it’s set to the result of [onInit](#parameter-oninit) +or [initial](#parameter-initial) if [onInit](#parameter-oninit) was not defined. + +--- + +### Return Type: `dispatch` + +Is type `UseCTAReturnTypeDispatch` + +https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L219-L225 + +Typescript Definition: +- [CTAInitial](#export-type--ctainitial-) + +A `function` with static read-only properties [dispatch.state](#return-type-dispatchstate) +and [dispatch.cta](#return-type-dispatchcta). + +Triggers re-render when [state](#return-type-state) or [dispatch.state.initial](#return-type-dispatchstateinitial) changes + +Parameters description will be covered by: + +- [dispatch.cta?.\['customAction'\]](#return-type-dispatchctacustomaction) +- [dispatch.cta.update](#return-type-dispatchctaupdate) +- [dispatch.cta.replace](#return-type-dispatchctareplace) +- [dispatch.cta.replaceInitial](#return-type-dispatchctareplaceinitial) +- [dispatch.cta.reset](#return-type-dispatchctareset) + +--- + +#### Return Type: `dispatch.cta` + +https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L223 + +Has predefined actions + +https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L192-L198 + +and custom actions if defined in [actions?.\['customAction'\]](#parameter-actionscustomaction). + +Typescript Definition: +- `Initial` extends [CTAInitial](#export-type--ctainitial-) + +--- + +##### Return Type: `dispatch.cta?.['customAction']` + +_Optional_ + +Custom call to action for changing [state](#return-type-state) + +Parameters are based on the expected `payload` you defined them in [Parameter: actions?.\['customAction'\]](#parameter-actionscustomaction) + +--- + +###### Return Type: `dispatch.cta?.['customAction']` with `payload` parameter + +
+ +Example for Return Type: `dispatch.cta?.['customAction']` with `payload` parameter + +```ts + +dispatch.cta.addToCount(5); + +// Alias for +dispatch({ + type: 'addToCount', + payload: 5 +}); + +// or +dispatch.cta.addToCount((ctaParam) => { + return ctaParam.previous.count + 10; +}); + +// Alias for +dispatch({ + type: 'addToCount', + payload: (ctaParam) => { + return ctaParam.previous.count + 10; + } +}); + +// or +dispatch.cta.addToCount((ctaParam) => { + // No re-render + return; +}); + +// Alias for +dispatch({ + type: 'addToCount', + payload: (ctaParam) => { + // No re-render + return; + } +}); + +``` + +
+ +--- + +###### Return Type: `dispatch.cta?.['customAction']` without parameter + +
+ +Example for dispatch.cta?.['customAction'] without parameter + +```ts + +dispatch.cta.incrementCount(); + +// Alias for +dispatch({ + type: 'incrementCount', +}); + +``` + +
+ +Effects +- [state](#return-type-state) = `state` change(s) based on [Parameter: actions?.\['customAction'\]](#parameter-actionscustomaction) definition. +- [dispatch.state.current](#return-type-dispatchstatecurrent) = same as [state](#return-type-state) +- [dispatch.state.changes](#return-type-dispatchstatechanges) + - = new differences between [dispatch.state.current](#return-type-dispatchstatecurrent) and [dispatch.state.initial](#return-type-dispatchstateinitial) + - = `null` if no difference. +- [dispatch.state.previous](#return-type-dispatchstateprevious) = previous [dispatch.state.current](#return-type-dispatchstatecurrent) + +--- + +##### Return Type: `dispatch.cta.update` + +Overloaded `function` for partially changing [state](#return-type-state) + +https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L196-L197 + +Typescript Definition: +- `Initial` extends [CTAInitial](#export-type--ctainitial-) +- [UseCTAReturnTypeDispatchState](#export-type--usectareturntypedispatchstate-) + +--- + +###### Return Type: `dispatch.cta.update` with `payload` parameter + +Accepts partial key/values from [Initial](#parameter-initial) and updates [state](#return-type-state) with partial change(s) + +https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L196 + +
+ +Example + +```ts + +dispatch.cta.update({ + // partial `state` change + search: 'update', + count: 8, +}); + +// Alias for +dispatch({ + type: 'update', + payload: { + // partial `state` change + search: 'update', + count: 8, + } +}); + +// or +dispatch.cta.update((ctaParam) => { + return { + // partial `state` change + search: 'update', + count: 8, + }; +}); + +// Alias for +dispatch({ + type: 'update', + payload: (ctaParam) => { + return { + // partial `state` change + search: 'update', + count: 8, + }; + } +}); + +// or +dispatch.cta.update((ctaParam) => { + // No re-render + return; +}); + +// Alias for +dispatch({ + type: 'update', + payload: (ctaParam) => { + // No re-render + return; + } +}); + +``` + +
+ +--- + +###### Return Type: `dispatch.cta.update` with `key` and `value` parameters + +https://github.com/rafde/react-hook-use-cta/blob/1e97f6ef6c5bc3d053cf64007bfea7c5c84877a0/src/types/UseCTAReturnTypeDispatch.ts#L197 + +Accepts a key from [Initial](#parameter-initial) and a corresponding value type for that key from [Initial](#parameter-initial)`[keyof Initial]` +and updates [state](#return-type-state) with partial change + + +
+ +Example + +```ts + +dispatch.cta.update('seatch', 'update'); // partial `state` change + +// Alias for +dispatch.cta.update({ + seatch: 'update', +}); + +``` + +
+ +Effects +- [state](#return-type-state) = new `state` with partial change(s). +- [dispatch.state.current](#return-type-dispatchstatecurrent) = new `state` with partial change(s). +- [dispatch.state.changes](#return-type-dispatchstatechanges) + - = new differences between [dispatch.state.current](#return-type-dispatchstatecurrent) and [dispatch.state.initial](#return-type-dispatchstateinitial) + - = `null` if no difference. +- [dispatch.state.previous](#return-type-dispatchstateprevious) = previous [dispatch.state.current](#return-type-dispatchstatecurrent) + +--- + +##### Return Type: `dispatch.cta.replace` + +Replace entire [state](#return-type-state) with a new `state`. + +https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L193 + +Typescript Definition: +- `Initial` extends [CTAInitial](#export-type--ctainitial-) +- [UseCTAReturnTypeDispatchState](#export-type--usectareturntypedispatchstate-) + +
+ +Example for Return Type: dispatch.cta.replace + +```ts + +dispatch.cta.replace({ + // new `state` + search: 'replace', + isFuzzy: false, + count: 8, +}); + +// Alias for +dispatch({ + type: 'replace', + payload: { + // new `state` + search: 'replace', + isFuzzy: false, + count: 8, + } +}); + +// or +dispatch.cta.replace((ctaParam) => { + return { + // new `state` + search: 'replace', + isFuzzy: false, + count: 8, + }; +}); + +// Alias for +dispatch({ + type: 'replace', + payload: (ctaParam) => { + return { + // new `state` + search: 'replace', + isFuzzy: false, + count: 8, + }; + } +}); + +// or +dispatch.cta.replace((ctaParam) => { + // No re-render + return; +}); + +// Alias for +dispatch({ + type: 'replace', + payload: (ctaParam) => { + // No re-render + return; + } +}); +``` + +
+ +Effects +- [state](#return-type-state) = new `state` +- [dispatch.state.current](#return-type-dispatchstatecurrent) = new `state` +- [dispatch.state.changes](#return-type-dispatchstatechanges) + - = new differences between [dispatch.state.current](#return-type-dispatchstatecurrent) and [dispatch.state.initial](#return-type-dispatchstateinitial) + - = `null` if no difference. +- [dispatch.state.previous](#return-type-dispatchstateprevious) = previous [dispatch.state.current](#return-type-dispatchstatecurrent) + +--- + +##### Return Type: `dispatch.cta.replaceInitial` + +Replace entire [dispatch.state.initial](#return-type-dispatchstateinitial) value with a new `initial` value. + +https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L194 + +Typescript Definition: +- `Initial` extends [CTAInitial](#export-type--ctainitial-) +- [UseCTAReturnTypeDispatchState](#export-type--usectareturntypedispatchstate-) + +
+ +Example for Return Type: dispatch.cta.replaceInitial + +```ts + +dispatch.cta.replaceInitial({ + // new `initial` + search: 'replaceInitial', + isFuzzy: true, + count: 5, +}); + +// Alias for +dispatch({ + type: 'replaceInitial', + payload: { + // new `initial` + search: 'replaceInitial', + isFuzzy: true, + count: 5, + } +}); + +// or +dispatch.cta.replaceInitial((ctaParam) => { + return { + // new `initial` + search: 'replaceInitial', + isFuzzy: true, + count: 5, + }; +}); + +// Alias for +dispatch({ + type: 'replaceInitial', + payload: (ctaParam) => { + return { + // new `initial` + search: 'replaceInitial', + isFuzzy: true, + count: 5, + }; + } +}); + +// or +dispatch.cta.replaceInitial((ctaParam) => { + // No re-render + return; +}); + +// Alias for +dispatch({ + type: 'replaceInitial', + payload: (ctaParam) => { + // No re-render + return; + } +}); + +``` + +
+ +Effects +- [dispatch.state.initial](#return-type-dispatchstateinitial) = new `initial` +- [dispatch.state.changes](#return-type-dispatchstatechanges) + - = new differences between [dispatch.state.current](#return-type-dispatchstatecurrent) and [dispatch.state.initial](#return-type-dispatchstateinitial) + - = `null` if no difference. + +--- + +##### Return Type: `dispatch.cta.reset` + +Overloaded `function` that differs in behavior when called with payload parameter and without parameter. + +https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L195 + +Typescript Definition: +- `Initial` extends [CTAInitial](#export-type--ctainitial-) +- [UseCTAReturnTypeDispatchState](#export-type--usectareturntypedispatchstate-) + +--- + +###### Return Type: `dispatch.cta.reset` without parameter + +Sets [state](#return-type-state) equal to [dispatch.state.initial](#return-type-dispatchstateinitial) + +
+ +Example for Return Type: dispatch.cta.reset without parameter + +```ts +dispatch.cta.reset(); + +// Alias for +dispatch({ + type: 'reset', +}); +``` + +
+ +Effects +- [state](#return-type-state) = [dispatch.state.initial](#return-type-dispatchstateinitial) +- [dispatch.state.current](#return-type-dispatchstatecurrent) = [dispatch.state.initial](#return-type-dispatchstateinitial) +- [dispatch.state.changes](#return-type-dispatchstatechanges) = `null` +- [dispatch.state.previous](#return-type-dispatchstateprevious) = previous [dispatch.state.current](#return-type-dispatchstatecurrent) + +--- + +###### Return Type: `dispatch.cta.reset` with `payload` parameter + +Sets [state](#return-type-state) and [dispatch.state.initial](#return-type-dispatchstateinitial) equal to `payload` + +
+ +Example for Return Type: dispatch.cta.reset with payload parameter + +```ts + +dispatch.cta.reset({ + // new `state` and `initial` + search: 'reset', + isFuzzy: true, + count: 10, +}); + +// Alias for +dispatch({ + type: 'reset', + payload: { + // new `state` and `initial` + search: 'reset', + isFuzzy: true, + count: 10, + } +}); + +// or +dispatch.cta.reset((ctaParam) => { + return { + // new `state` and `initial` + search: 'reset', + isFuzzy: true, + count: 10, + }; +}); + +// Alias for +dispatch({ + type: 'reset', + payload: (ctaParam) => { + return { + // new `state` and `initial` + search: 'reset', + isFuzzy: true, + count: 10, + }; + } +}); + +// or +dispatch.cta.reset((ctaParam) => { + // No re-render + return; +}); + +// Alias for +dispatch({ + type: 'reset', + payload: (ctaParam) => { + // No re-render + return; + } +}); +``` + +
+ +Effects +- [state](#return-type-state) = new `state` +- [dispatch.state.current](#return-type-dispatchstatecurrent) = new `state` +- [dispatch.state.changes](#return-type-dispatchstatechanges) = `null` +- [dispatch.state.initial](#return-type-dispatchstateinitial) = new `state` +- [dispatch.state.previous](#return-type-dispatchstateprevious) = previous [dispatch.state.current](#return-type-dispatchstatecurrent) + +--- + +#### Return Type: `dispatch.state` + +https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L224 + +Is of type `UseCTAReturnTypeDispatchState`. + +https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L212-L217 + +This is extra data information that can be referenced for certain changes over time. + +Typescript Definition: +- [CTAInitial](#export-type--ctainitial-) + +--- + +##### Return Type: `dispatch.state.current` + +https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L214 + +The value is equal to [Return Type: state](#return-type-dispatchstate) + +Typescript Definition: +- `Initial` extends [CTAInitial](#export-type--ctainitial-) + +--- + +##### Return Type: `dispatch.state.initial` + +https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L215 + +Starts of equal to [initial](#parameter-initial) or the result of [onInit](#parameter-oninit). + +It can be changed with [dispatch.cta.replaceInitial](#return-type-dispatchctareplaceinitial) +or [dispatch.cta.reset with payload parameter](#return-type-dispatchctareset-with-payload-parameter) + +Typescript Definition: +- `Initial` extends [CTAInitial](#export-type--ctainitial-) + +--- + +##### Return Type: `dispatch.state.changes` + +https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L213 + +- `Partial`: When key/values of [dispatch.state.current](#return-type-dispatchstatecurrent) are not equal to + [dispatch.state.initial](#return-type-dispatchstateinitial) Example: + ```ts + dispatch.state.initial /* = { + search: '', + isFuzzy: true, + count: 1, + } */ + + dispatch.state.current /* = { + search: 'current', + isFuzzy: true, + count: 1, + } */ + + dispatch.state.changes /* = { + search: 'current', + } */ + + if ( dispatch.state.changes ) { + console.log('state has changes') + } + ``` +- `null`: When the key/values [dispatch.state.initial](#return-type-dispatchstateinitial) + and [dispatch.state.current](#return-type-dispatchstatecurrent) are equal. Example: + ```ts + dispatch.state.initial /* = { + search: 'current', + isFuzzy: true, + count: 1, + } */ + + dispatch.state.current /* = { + search: 'current', + isFuzzy: true, + count: 1, + } */ + + dispatch.state.changes /* = null */ + + if ( !dispatch.state.changes ) { + console.log('No changes to state') + } + ``` + +Typescript Definition: +- `Initial` extends [CTAInitial](#export-type--ctainitial-) + +--- + +##### Return Type: `dispatch.state.previous` + +https://github.com/rafde/react-hook-use-cta/blob/0ed13652508f2b3afb74cd7d35c920a3291b5620/src/types/UseCTAReturnTypeDispatch.ts#L216 + +Equal to the previous [dispatch.state.current](#return-type-dispatchstatecurrent) value. + +Typescript Definition: +- `Initial` extends [CTAInitial](#export-type--ctainitial-) + +--- + +## Typescript `export`s + +https://github.com/rafde/react-hook-use-cta/blob/bf4d06d68f391b8ed1a6a641c051338d4de1e70d/src/index.ts#L22-L32 + +--- + +## `export type { CTAInitial, }` + +https://github.com/rafde/react-hook-use-cta/blob/9e9206f1ff06e2de5adcde5d107d9d847e210063/src/types/CTAInitial.ts#L1 + +--- + +## `export type { CustomCTAParam, }` + +https://github.com/rafde/react-hook-use-cta/blob/adfd2a0448f08a4d1374db0136f77dde9c64da7a/src/types/CustomCTAParam.ts#L11-L16 + +--- + +## `export type { UseCTAParameter, }` + +See [Parameter](#parameter) + +--- + +## `export type { UseCTAReturnTypeDispatchState, }` + +See [Return Type: dispatch](#return-type-dispatch) + +## `export type { UseCTAReturnTypeDispatch, }` + +See [Return Type: dispatch](#return-type-dispatch) + +--- + +## `export type { UseCTAReturnType, }` + +See [Return Type](#return-type) + +--- + +