@ewb/reach-react
Version:
React Resource and Fetch stuff
70 lines (69 loc) • 3.26 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.useField = void 0;
const react_1 = require("react");
const reach_1 = require("@ewb/reach");
const ReachContext_1 = require("./ReachContext");
function useField(crud, key, props = {}) {
const { path, data, schema, idKey } = crud.state;
const value = react_1.useMemo(() => getDotValue(data, String(key).split('.')), [data, key]);
const ref = react_1.useRef(value);
const service = react_1.useContext(ReachContext_1.ReachContext);
const reach = react_1.useMemo(() => new reach_1.Reach(service), [service]);
const [state, setState] = react_1.useState({
value: ref.current,
busy: false,
});
const field = react_1.useMemo(() => {
if (!schema[key]) {
throw new Error(`useField was used with edit field that was not defined. Add ${key} to field object`);
}
const id = `${data[idKey]}-${key}`;
const edited = ref.current !== state.value;
// @ts-ignore
return Object.assign(Object.assign({}, schema[key]), { key, id, edited, value: state.value });
}, [state.value, key, idKey]);
const _id = data[idKey];
const save = react_1.useCallback((v = ref.current) => __awaiter(this, void 0, void 0, function* () {
try {
setState((s) => (Object.assign(Object.assign({}, s), { busy: true })));
yield reach.api(`${path}/${_id}`, { method: 'PATCH', body: { [key]: v } });
ref.current = v;
setState((s) => (Object.assign(Object.assign({}, s), { busy: false, value: v })));
}
catch (error) {
setState((s) => (Object.assign(Object.assign({}, s), { busy: false, error })));
}
}), [path, reach, _id, key]);
const setValue = react_1.useCallback((value, disableAutoSave = props.disableAutoSave) => {
ref.current = value;
if (!disableAutoSave) {
return save(ref.current);
}
}, [save]);
react_1.useEffect(() => {
if (value !== ref.current) {
ref.current = value;
setState((s) => (Object.assign(Object.assign({}, s), { value })));
}
}, [value]);
return [state.busy, field, state.error, setValue];
}
exports.useField = useField;
function getDotValue(data, arr) {
const key = arr[0];
if (key && data[key]) {
if (typeof data[key] === 'object')
return getDotValue(data[key], arr.slice(1));
}
return data[key];
}