The useParcelBuffer function is a React hook. Its job is to control the flow of Parcel changes by providing a buffer.
It receives a Parcel (via parcel) and provides a Parcel of its own (referred to as innerParcel). innerParcel
initially has the same contents as parcel
. Changes to innerParcel
will be applied immediately like normal.
When buffering is enabled, these changes will not be propagated up through parcel
, and are instead held in an internal buffer. These can be released later, either explicitly by calling control.submit(), or automatically if debounce is being used.
Please refer to the "Submitting Forms" example to see how this buffering behaves
import useParcelBuffer from 'react-dataparcels/useParcelBuffer';
let [innerParcel, control] = useParcelBuffer({
parcel: Parcel,
// optional
buffer?: boolean,
debounce?: number,
beforeChange?: ParcelUpdater|ParcelUpdater[]
});
parcel: Parcel
The useParcelBuffer hook must be passed a parcel
, the Parcel which the buffer will apply to.
Whenever a useParcelBuffer hook receives a new Parcel via props, its default behaviour is to:
This is safe default behaviour because changes in the buffer may not be compatible with the new Parcel's data shape. However it may be user unfriendly in some cases, depending on when and how often the parcel updates.
If you would like to keep the changes in the buffer, and you know that buffered changes will always be compatible with any new Parcel's data shape, consider using useParcelForm.rebase or useParcelState.rebase.
buffer?: boolean = true // optional
When buffer
is true, changes that occur to innerParcel
will be caught in useParcelBuffer's buffer, until released explicitly by calling control.submit(), or automatically if debounce is being used.
When buffer
is false, changes will propagate up to parcel
immediately.
debounce?: number // optional
If set, debounce
will debounce any changes that enter the buffer. The number indicates the number of milliseconds to debounce.
This can be used to make autosaving forms.
When the innerParcel
sends a change, the useParelBuffer hook will catch it and prevent it from being propagated out of the buffer.
The useParcelBuffer hooks waits until no new changes have occured for debounce
number of milliseconds. It then releases all the changes it has buffered, all together in a single change request.
beforeChange?: ParcelUpdater|ParcelUpdater[] // optional
type ParcelUpdater = (value: any, changeRequest: ChangeRequest) => any
type ParcelUpdater = asNode((node: ParcelNode, changeRequest: ChangeRequest) => ParcelNode);
type ParcelUpdater = asChildNodes((nodes: any, changeRequest: ChangeRequest) => any);
The beforeChange
parameter accepts either a single function, or an array of functions. Whenever a new parcel
is taken into useParcelBuffer from params, and whenever the useParcelBuffer hook recieves a change from below, the change is passed through each beforeChange
function.
Internally the useParcelBuffer hook uses Parcel.modifyUp() on each of the beforeChange
functions. If more than one function is passed to beforeChange
, the change will go through the first function in the array first, then the second etc.
This is particularly useful for setting derived data, and plugins such as validation are built to be passed into beforeChange
.
This method is safe to use in most simple cases, but in some cases it should not be used:
To find out why, and what to do about it, please read about parcel updaters.
// parcel.value is "ABC"
let [innerParcel] = useParcelBuffer({
parcel,
beforeChange: value => value.toLowerCase()
});
// ^ "ABC" will be passed through `beforeChange`
// and useParcelBuffer's Parcel will contain a value of "abc"
// parcel.value is now "abc"
innerParcel.set("HELLO");
// ^ "HELLO" will be passed through `beforeChange`
// and useParcelBuffer's Parcel will contain a value of "hello"
// parcel.value is now "hello"
[innerParcel: Parcel, control: ParcelHookControl]
innerParcel: Parcel
The first element of the returned array is the innerParcel
, a Parcel that contains the current state of parcel
with all the changes in the buffer applied to it. When buffering is enabled, any changes that innerParcel
receives will go into the buffer.
control: ParcelHookControl
The second element of the returned array is a ParcelHookControl instance.
class ParcelHookControl {
submit: Function,
reset: Function,
buffered: boolean,
actions: Action[]
}
When called, this function will release all changes in the buffer.
When called, this function will remove all changes in the buffer, and reset the data in innerParcel
to be the same as parcel
.
This boolean is true when there are any changes in the buffer, or false if the buffer is empty.
An array of actions that are currently in the buffer.