A somewhat flexible react hook alternative to React.useReducer
. Written in Typescript.
Table of Contents: Parameter
Table of Contents: Return Type
Table of Contents: Typescript exports
react-hook-use-cta fast-equals
npm i react-hook-use-cta fast-equals
react-hook-use-cta/src/index.ts
Lines 9 to 14 in 9e9206f
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
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>
</>
}
Required
Key/value object
of type UseCTAParameter
react-hook-use-cta/src/types/UseCTAParameter.ts
Lines 4 to 11 in 9e9206f
Typescript Definition:
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
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
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
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:
You can define your own custom actions to handle payloads to your specifications.
Typescript signature:
react-hook-use-cta/src/types/UseCTAParameterActionsRecordProp.ts
Lines 6 to 14 in adfd2a0
Typescript Definitions:
Call to action:
Example for Parameter: actions?.['customAction']
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}</>
}
Custom actions' first parameter:
react-hook-use-cta/src/types/CustomCTAParam.ts
Lines 11 to 16 in bf4d06d
extends UseCTAReturnTypeDispatchState with 4 additional functions that affect the behavior of the action.
react-hook-use-cta/src/types/CustomCTAParam.ts
Lines 12 to 15 in bf4d06d
Accepts result
and options
If predefined actions were augmented, {useCustom: false}
will bypass them and use default predefined behavior.
Returns instance of ReplaceActionType
Returning ReplaceActionType
will produce the same outcome as dispatch.cta.replace
Example for CustomCTAParam.replaceAction
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,
}
},
},
});
Returns instance of ReplaceInitialActionType
Returning ReplaceIntialActionType
will produce the same outcome as dispatch.cta.replaceInitial
Example for CustomCTAParam.replaceInitialAction
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,
}
},
},
});
Returns instance of ResetActionType
Returning ResetActionType
will produce the same outcome as dispatch.cta.reset with payload parameter
Example for CustomCTAParam.resetAction
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,
}
},
},
});
Returns instance of UpdateActionType
Returning UpdateActionType
will produce the same outcome as dispatch.cta.update
Example for CustomCTAParam.updateAction
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
},
},
});
payload
s can be:
undefined
- optional or required where the value can be anything
- Initial type
Partial<Initial>
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
Array with two values: [state, dispatch]
of type UseCTAReturnType
react-hook-use-cta/src/types/UseCTAReturnType.ts
Lines 4 to 10 in bf4d06d
Typescript Definitions:
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.
Is type UseCTAReturnTypeDispatch
react-hook-use-cta/src/types/UseCTAReturnTypeDispatch.ts
Lines 219 to 225 in 0ed1365
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
Has predefined actions
react-hook-use-cta/src/types/UseCTAReturnTypeDispatch.ts
Lines 192 to 198 in 0ed1365
and custom actions if defined in actions?.['customAction'].
Typescript Definition:
Initial
extends CTAInitial
Optional
Custom call to action for changing state
Parameters are based on the expected payload
you defined them in Parameter: actions?.['customAction']
Example for 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;
}
});
Example for 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
Overloaded function
for partially changing state
react-hook-use-cta/src/types/UseCTAReturnTypeDispatch.ts
Lines 196 to 197 in 0ed1365
Typescript Definition:
Initial
extends CTAInitial- UseCTAReturnTypeDispatchState
Accepts partial key/values from Initial and updates state with partial change(s)
Example
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;
}
});
Accepts a key from Initial and a corresponding value type for that key from Initial[keyof Initial]
and updates state with partial change
Example
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
Replace entire state with a new state
.
Typescript Definition:
Initial
extends CTAInitial- UseCTAReturnTypeDispatchState
Example for Return Type: dispatch.cta.replace
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
Replace entire dispatch.state.initial value with a new initial
value.
Typescript Definition:
Initial
extends CTAInitial- UseCTAReturnTypeDispatchState
Example for Return Type: dispatch.cta.replaceInitial
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.
Overloaded function
that differs in behavior when called with payload parameter and without parameter.
Typescript Definition:
Initial
extends CTAInitial- UseCTAReturnTypeDispatchState
Sets state equal to dispatch.state.initial
Example for Return Type: dispatch.cta.reset
without parameter
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
Sets state and dispatch.state.initial equal to payload
Example for Return Type: dispatch.cta.reset
with payload
parameter
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
Is of type UseCTAReturnTypeDispatchState
.
react-hook-use-cta/src/types/UseCTAReturnTypeDispatch.ts
Lines 212 to 217 in 0ed1365
This is extra data information that can be referenced for certain changes over time.
Typescript Definition:
The value is equal to Return Type: state
Typescript Definition:
Initial
extends CTAInitial
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
Partial<Initial>
: When key/values of dispatch.state.current are not equal to dispatch.state.initial Example: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: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
Equal to the previous dispatch.state.current value.
Typescript Definition:
Initial
extends CTAInitial
react-hook-use-cta/src/index.ts
Lines 22 to 32 in bf4d06d
react-hook-use-cta/src/types/CustomCTAParam.ts
Lines 11 to 16 in adfd2a0
See Parameter
See Return Type