Add new hook useSubmitHookWith to dynamically inject the submit hooks #1924

This commit is contained in:
LASER-Yi 2022-10-25 23:39:57 +08:00
parent c08ba5f793
commit 1766ceeabc
4 changed files with 42 additions and 24 deletions

View File

@ -11,6 +11,7 @@ import { useLatestEnabledLanguages, useLatestProfiles } from ".";
import { Selector, SelectorProps } from "../components";
import { useFormActions } from "../utilities/FormValues";
import { BaseInput } from "../utilities/hooks";
import { useSubmitHookWith } from "../utilities/HooksProvider";
type LanguageSelectorProps = Omit<
MultiSelectorProps<Language.Info>,
@ -25,6 +26,10 @@ export const LanguageSelector: FunctionComponent<
const enabled = useLatestEnabledLanguages();
const { setValue } = useFormActions();
useSubmitHookWith(settingKey, (value: Language.Info[]) =>
value.map((v) => v.code2)
);
const wrappedOptions = useSelectorOptions(options, (value) => value.name);
return (

View File

@ -13,6 +13,7 @@ import { Column } from "react-table";
import { useLatestEnabledLanguages, useLatestProfiles } from ".";
import { languageProfileKey } from "../keys";
import { useFormActions } from "../utilities/FormValues";
import { useSubmitHookWith } from "../utilities/HooksProvider";
const Table: FunctionComponent = () => {
const profiles = useLatestProfiles();
@ -26,6 +27,8 @@ const Table: FunctionComponent = () => {
[profiles]
);
useSubmitHookWith(languageProfileKey, (value) => JSON.stringify(value));
const { setValue } = useFormActions();
const modals = useModals();

View File

@ -1,13 +1,14 @@
import { LOG } from "@/utilities/console";
import {
createContext,
FunctionComponent,
useCallback,
useContext,
useEffect,
useMemo,
useRef,
useState,
} from "react";
import { enabledLanguageKey, languageProfileKey } from "../keys";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type HookType = (value: any) => unknown;
@ -50,20 +51,40 @@ export function useSubmitHooks() {
return context;
}
export function useSubmitHookWith(key: string, fn?: HookType) {
const fnRef = useRef(fn);
fnRef.current = fn;
const hooks = useSubmitHooks();
useEffect(() => {
const currentFn = fnRef.current;
if (currentFn) {
LOG("info", "Adding submit hook for", key);
hooks.add(key, currentFn);
}
return () => {
LOG("info", "Removing submit hook for", key);
hooks.remove(key);
};
}, [key, hooks]);
}
export function useSubmitHooksSource(): SubmitHookModifierType {
const [submitHooks, setSubmitHooks] = useState<SubmitHookType>({
[languageProfileKey]: (value) => JSON.stringify(value),
[enabledLanguageKey]: (value: Language.Info[]) => value.map((v) => v.code2),
});
const [submitHooks, setSubmitHooks] = useState<SubmitHookType>({});
const hooksRef = useRef(submitHooks);
hooksRef.current = submitHooks;
const invokeHooks = useCallback((settings: LooseObject) => {
const hooks = hooksRef.current;
for (const key in settings) {
if (key in hooks) {
LOG("info", "Running submit hook for", key, settings[key]);
const value = settings[key];
const fn = hooks[key];
settings[key] = fn(value);
LOG("info", "Finish submit hook", key, settings[key]);
}
}
}, []);
@ -78,7 +99,10 @@ export function useSubmitHooksSource(): SubmitHookModifierType {
const removeHook = useCallback((key: string) => {
setSubmitHooks((hooks) => {
const newHooks = { ...hooks };
delete newHooks[key];
if (key in newHooks) {
delete newHooks[key];
}
return newHooks;
});

View File

@ -1,13 +1,13 @@
import { LOG } from "@/utilities/console";
import { get, isNull, isUndefined, uniqBy } from "lodash";
import { useCallback, useEffect, useMemo, useRef } from "react";
import { useCallback, useMemo, useRef } from "react";
import {
FormKey,
useFormActions,
useStagedValues,
} from "../utilities/FormValues";
import { useSettings } from "../utilities/SettingsProvider";
import { useSubmitHooks } from "./HooksProvider";
import { useSubmitHookWith } from "./HooksProvider";
export interface BaseInput<T> {
disabled?: boolean;
@ -51,23 +51,9 @@ export function useSettingValue<T>(
const settings = useSettings();
const optionsRef = useRef(options);
optionsRef.current = options;
const submitHooks = useSubmitHooks();
useEffect(() => {
const onSubmit = optionsRef.current?.onSubmit;
if (onSubmit) {
LOG("info", "Adding submit hook for", key);
submitHooks.add(key, onSubmit);
}
return () => {
if (key in submitHooks) {
LOG("info", "Removing submit hook for", key);
submitHooks.remove(key);
}
};
}, [key, submitHooks]);
useSubmitHookWith(key, options?.onSubmit);
const originalValue = useMemo(() => {
const onLoaded = optionsRef.current?.onLoaded;