react-hook-use-cta v0.0.1-7
react-hook-use-cta: useCTA (use Call To Action)
A somewhat flexible react hook alternative to React.useReducer
. Written in Typescript.
Table of Contents
- Return Type
Installation
react-hook-use-cta fast-equals
NPM
npm i react-hook-use-cta fast-equals
export { useCTA }
Usage
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}</>
}
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 <>
<div>{state.search}</div>
<div>{dispatch.state.initial.search}</div>
<div>{dispatch.state.changes?.search}</div>
<div>{dispatch.state.previous.search}</div>
</>
}
Parameter
Required
Key/value object
of type UseCTAParameter
Typescript Definition:
Parameter: initial
Required
Similar to React.useReducer
initialArg
parameter,
but it only takes key/value object
that defines the shape of your state.
Values can be anything that strictDeepEqual from fast-equals supports.
Typescript Definition:
Initial
extends CTAInitial
Parameter: onInit
Optional
Similar to React.useReducer
init
parameter. Called on first time render. A function
that is called to replace initial value.
Typescript Definition:
Initial
extends 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 or dispatch.state.initial
Predefine actions
There are predefined actions that can be augmented with the following signatures:
Augmenting these actions will affect custom actions.
Typescript Definition:
Predefined calls to action:
Parameter: actions?.['customAction']
You can define your own custom actions to handle payloads to your specifications.
Typescript signature:
Typescript Definitions:
Call to action:
- `dispatch.cta?.['customAction'] - dispatch.cta?.['customAction'] with payload parameter - dispatch.cta?.['customAction'] without parameter
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:
extends UseCTAReturnTypeDispatchState with 4 additional functions that affect the behavior of the action.
Accepts result
and options
If predefined actions were augmented, {useCustom: false}
will bypass them and use default predefined behavior.
actions?.['customAction']
1st Parameter: CustomCTAParam.replaceAction
Returns instance of ReplaceActionType
Returning ReplaceActionType
will produce the same outcome as dispatch.cta.replace
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
Returns instance of ReplaceInitialActionType
Returning ReplaceIntialActionType
will produce the same outcome as dispatch.cta.replaceInitial
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
Returns instance of ResetActionType
Returning ResetActionType
will produce the same outcome as dispatch.cta.reset with payload parameter
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
Returns instance of UpdateActionType
Returning UpdateActionType
will produce the same outcome as dispatch.cta.update
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 type
Partial<Initial>
type
actions?.['customAction']
Return Type
Return type can be
- Falsy value: to not trigger re-render.
Partial<Initial>
: triggers re-render if it changes the values of state. Works the same as CustomCTAParam.updateActionReplaceActionType
: See CustomCTAParam.replaceActionReplaceInitialActionType
: See CustomCTAParam.replaceInitialActionResetActionType
: See CustomCTAParam.resetActionUpdateActionType
: See CustomCTAParam.updateAction
Return Type
Array with two values: [state, dispatch]
of type UseCTAReturnType
Typescript Definitions:
Return Type: state
Key/value object
of type CTAInitial
The current state
. During the first render, it’s set to the result of onInit
or initial if onInit was not defined.
Return Type: dispatch
Is type UseCTAReturnTypeDispatch
Typescript Definition:
A function
with static read-only properties dispatch.state
and dispatch.cta.
Triggers re-render when state or dispatch.state.initial changes
Parameters description will be covered by:
- dispatch.cta?.['customAction']
- dispatch.cta.update
- dispatch.cta.replace
- dispatch.cta.replaceInitial
- dispatch.cta.reset
Return Type: dispatch.cta
Has predefined actions
and custom actions if defined in actions?.['customAction'].
Typescript Definition:
Initial
extends CTAInitial
Return Type: dispatch.cta?.['customAction']
Optional
Custom call to action for changing state
Parameters are based on the expected payload
you defined them in Parameter: actions?.['customAction']
Return Type: dispatch.cta?.['customAction']
with payload
parameter
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
dispatch.cta.incrementCount();
// Alias for
dispatch({
type: 'incrementCount',
});
Effects
- state =
state
change(s) based on Parameter: actions?.['customAction'] definition. - dispatch.state.current = same as state
- dispatch.state.changes
- = new differences between dispatch.state.current and dispatch.state.initial
- =
null
if no difference. - dispatch.state.previous = previous dispatch.state.current
Return Type: dispatch.cta.update
Overloaded function
for partially changing state
Typescript Definition:
Initial
extends CTAInitial- UseCTAReturnTypeDispatchState
Return Type: dispatch.cta.update
with payload
parameter
Accepts partial key/values from Initial and updates state with partial change(s)
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
Accepts a key from Initial and a corresponding value type for that key from Initial[keyof Initial]
and updates state with partial change
dispatch.cta.update('seatch', 'update'); // partial `state` change
// Alias for
dispatch.cta.update({
seatch: 'update',
});
Effects
- state = new
state
with partial change(s). - dispatch.state.current = new
state
with partial change(s). - dispatch.state.changes
- = new differences between dispatch.state.current and dispatch.state.initial
- =
null
if no difference. - dispatch.state.previous = previous dispatch.state.current
Return Type: dispatch.cta.replace
Replace entire state with a new state
.
Typescript Definition:
Initial
extends CTAInitial- UseCTAReturnTypeDispatchState
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 = new
state
- dispatch.state.current = new
state
- dispatch.state.changes
- = new differences between dispatch.state.current and dispatch.state.initial
- =
null
if no difference. - dispatch.state.previous = previous dispatch.state.current
Return Type: dispatch.cta.replaceInitial
Replace entire dispatch.state.initial value with a new initial
value.
Typescript Definition:
Initial
extends CTAInitial- UseCTAReturnTypeDispatchState
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 = new
initial
- dispatch.state.changes
- = new differences between dispatch.state.current and dispatch.state.initial
- =
null
if no difference.
Return Type: dispatch.cta.reset
Overloaded function
that differs in behavior when called with payload parameter and without parameter.
Typescript Definition:
Initial
extends CTAInitial- UseCTAReturnTypeDispatchState
Return Type: dispatch.cta.reset
without parameter
Sets state equal to dispatch.state.initial
dispatch.cta.reset();
// Alias for
dispatch({
type: 'reset',
});
Effects
- state = dispatch.state.initial
- dispatch.state.current = dispatch.state.initial
- dispatch.state.changes =
null
- dispatch.state.previous = previous dispatch.state.current
Return Type: dispatch.cta.reset
with payload
parameter
Sets state and dispatch.state.initial equal to payload
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 = new
state
- dispatch.state.current = new
state
- dispatch.state.changes =
null
- dispatch.state.initial = new
state
- dispatch.state.previous = previous dispatch.state.current
Return Type: dispatch.state
Is of type UseCTAReturnTypeDispatchState
.
This is extra data information that can be referenced for certain changes over time.
Typescript Definition:
Return Type: dispatch.state.current
The value is equal to Return Type: state
Typescript Definition:
Initial
extends CTAInitial
Return Type: dispatch.state.initial
Starts of equal to initial or the result of onInit.
It can be changed with dispatch.cta.replaceInitial or dispatch.cta.reset with payload parameter
Typescript Definition:
Initial
extends CTAInitial
Return Type: dispatch.state.changes
Partial<Initial>
: When key/values of dispatch.state.current are not equal to dispatch.state.initial 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 and dispatch.state.current 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
Return Type: dispatch.state.previous
Equal to the previous dispatch.state.current value.
Typescript Definition:
Initial
extends CTAInitial
Typescript export
s
export type { CTAInitial, }
export type { CustomCTAParam, }
export type { UseCTAParameter, }
See Parameter
export type { UseCTAReturnTypeDispatchState, }
export type { UseCTAReturnTypeDispatch, }
export type { UseCTAReturnType, }
See Return Type