Skip to content
Snippets Groups Projects
Commit 0bee5721 authored by Remi Lazarini's avatar Remi Lazarini Committed by Loïc Correnson
Browse files

[Ivette] fix useBuffer

parent 10fb767a
No related branches found
No related tags found
No related merge requests found
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import Events from 'events'; import Events from 'events';
import React, { useReducer } from 'react'; import React from 'react';
import * as Dome from 'dome'; import * as Dome from 'dome';
import * as Utils from 'dome/misc/utils'; import * as Utils from 'dome/misc/utils';
import { SVG } from 'dome/controls/icons'; import { SVG } from 'dome/controls/icons';
...@@ -162,69 +162,6 @@ export class BufferController { ...@@ -162,69 +162,6 @@ export class BufferController {
removeError(): void { this.errors--; } removeError(): void { this.errors--; }
} }
interface BufferState<A> {
modified: boolean,
bvalue: A,
berror: FieldError
}
interface BufferActionDispatch<A> {
type: "reset" | "commit" | "change",
remote: BufferController,
reset?: A,
onChanged?: Callback<A>,
payload?: Partial<BufferState<A>>
}
type BufferReducer<A> = (
state: BufferState<A>,
action: BufferActionDispatch<A>
) => BufferState<A>;
/**
* Dispatch function for useBuffer hook.
*/
function bufferReducer<A>(
state: BufferState<A>, action: BufferActionDispatch<A>
): BufferState<A> {
const { bvalue, berror } = state;
const { type, remote, reset, onChanged, payload } = action;
const getResetState = (): BufferState<A> => {
return reset ?
{ ...state, bvalue: reset, berror: undefined, modified: false } :
state;
};
switch(type) {
case "reset": {
!isValid(berror) && reset && remote.removeError();
return getResetState();
}
case "commit": {
if(isValid(berror)) {
onChanged && onChanged(bvalue, undefined, false);
return { ...state, modified: false };
} else {
reset && remote.removeError();
return getResetState();
}
}
case "change": {
const newError = payload && payload.berror;
if(!isValid(berror) && isValid(newError)) {
remote.removeError();
} else if(isValid(berror) && !isValid(newError)) {
remote.addError();
}
return { ...state, ...payload };
}
default: {
return state;
}
}
}
/** /**
Insert a temporary buffer to stack modifications. Values are imported from Insert a temporary buffer to stack modifications. Values are imported from
the input state, and modifications are stacked into an internal buffer. the input state, and modifications are stacked into an internal buffer.
...@@ -248,62 +185,60 @@ export function useBuffer<A>( ...@@ -248,62 +185,60 @@ export function useBuffer<A>(
): FieldState<A> ): FieldState<A>
{ {
const { value, error, reset, onChanged } = state; const { value, error, reset, onChanged } = state;
const [ buffer, dispatch ] = useReducer<BufferReducer<A>>(bufferReducer, { const [ modified, setModified ] = React.useState(false);
modified: false, const [ buffer, setBuffer ] = React.useState<A>(value);
bvalue: value, const [ berror, setBerror ] = React.useState<FieldError>(error);
berror: error,
});
const { modified, berror, bvalue } = buffer;
// --- Reset // --- Reset
React.useEffect(() => { React.useEffect(() => {
if (modified) { if (modified) {
const doReset = (): void => { const doReset = (): void => {
dispatch({ !isValid(berror) && remote.removeError();
type: "reset", setModified(false);
remote: remote, setBuffer(reset ?? value);
reset: reset ?? value setBerror(undefined);
});
}; };
remote.onReset(doReset); remote.onReset(doReset);
return () => remote.offReset(doReset); return () => remote.offReset(doReset);
} else return; } else return;
}, [remote, modified, value, reset]); }, [remote, modified, value, berror, reset]);
// --- Commit // --- Commit
React.useEffect(() => { React.useEffect(() => {
if(modified) { if(modified) {
const doCommit = (): void => { const doCommit = (): void => {
dispatch({ if(isValid(berror)) {
type: "commit", setModified(false);
remote: remote, onChanged(buffer, undefined, false);
reset: reset ?? value, } else {
onChanged remote.removeError();
}); setModified(false);
setBuffer(reset ?? value);
setBerror(undefined);
}
}; };
remote.onCommit(doCommit); remote.onCommit(doCommit);
return () => remote.offCommit(doCommit); return () => remote.offCommit(doCommit);
} else return; } else return;
}, [remote, modified, value, reset, bvalue, onChanged]); }, [remote, modified, value, berror, buffer, reset, onChanged]);
// --- Callback // --- Callback
const onLocalChange = React.useCallback( const onLocalChange = React.useCallback(
(newValue, newError, isReset) => { (newValue, newError, isReset) => {
dispatch({ if(!isValid(berror) && isValid(newError)) {
type: "change", remote.removeError();
remote: remote, } else if(isValid(berror) && !isValid(newError)) {
payload: { remote.addError();
modified: !isReset, }
bvalue: newValue, setModified(!isReset);
berror: newError, setBuffer(newValue);
} setBerror(newError);
}); if (isReset && (equal ? !equal(newValue, value) : (newValue !== value)))
if (isReset && (equal ? equal(newValue, value) : (newValue !== value)))
onChanged(newValue, newError, isReset); onChanged(newValue, newError, isReset);
}, [value, onChanged, equal, remote]); }, [value, onChanged, equal, berror, remote]);
return { return {
value: modified ? bvalue : value, value: modified ? buffer : value,
error: modified ? berror : error, error: modified ? berror : error,
reset: reset ?? (modified ? value : undefined), reset: reset ?? (modified ? value : undefined),
onChanged: onLocalChange, onChanged: onLocalChange,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment