mt-flowbite-react
Version:
Official React components built for Flowbite and Tailwind CSS
98 lines (97 loc) • 3.6 kB
JavaScript
'use client';
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { createContext, useContext, useEffect, useRef } from 'react';
import { create, useStore } from 'zustand';
import { persist, subscribeWithSelector } from 'zustand/middleware';
import { useResFormStore } from './mtform.slice';
export const createResItemSlice = (set) => ({
setResItemSomeValue: () => set((state) => ({ resItemSomeValue: state.resItemSomeValue })),
});
export const createFormFieldStore = (initProps) => {
const DEFAULT_PROPS = {
id: 'demo-form1',
name: '',
};
return create()(persist(subscribeWithSelector((set, get) => ({
...DEFAULT_PROPS,
isOpenDebug: false,
isDesignEnabled: true,
...initProps,
setValue(value) {
set({ ...get(), value });
},
setOpenDebug(isOpenDebug) {
set({ ...get(), isOpenDebug });
},
// setDesignEnabled(isDesignEnabled) {
// set({ ...get(), isDesignEnabled })
// },
})), {
name: `form-field-${initProps?.id}`,
version: 1,
skipHydration: true,
onRehydrateStorage(state) {
// state.loadFormData()
},
migrate(persistedState, version) {
console.log('persistedState', version, persistedState);
return persistedState;
},
}));
};
//-----------context
const Context = createContext(null);
export function FormFieldProvider({ children, ...props }) {
// const value = useResFormStore(x => x.values[props.name!])
const formStore = useResFormStore();
const storeRef = useRef();
if (!storeRef.current) {
storeRef.current = createFormFieldStore(props);
}
// useEffect(() => {
// storeRef.current?.getState().setValue(value)
// }, [ value ])
useEffect(() => {
//提示: 优化:目前 field input 内部值变更后,会触发 form values的变更,导致整个表单重新渲染。
// 如果这对性能造成影响,可以考虑在formField 内部使用value state,在失去焦点后,才setFromValues
// 第二个思路是,使用第二个values,用于存储内部的表单值,将渲染值和内部值分开使用。
const unsubOnFormValueChanged = formStore.subscribe((state) => state.values, (values) => {
storeRef.current?.getState().setValue(values[props.name]);
}, {
fireImmediately: true,
});
return () => {
unsubOnFormValueChanged();
};
}, []);
return (_jsxs(Context.Provider, { value: storeRef.current, children: [children, _jsx(SubscriptionSetup, {})] }));
}
//------------事件订阅
function SubscriptionSetup() {
const store = useFormFieldStore();
const formStore = useResFormStore();
const fieldName = useFormFieldStore((x) => x.name);
useEffect(() => {
const unsubOnFieldValueChanged = store.subscribe((state) => state.value, (value) => {
formStore.getState().setFormValue(fieldName, value);
}, {
fireImmediately: true,
});
return () => {
unsubOnFieldValueChanged();
};
}, []);
return _jsx(_Fragment, {});
}
export function useFormFieldStore(selector, equals) {
const store = useContext(Context);
if (!store)
throw new Error('Missing FormFieldProvider');
if (selector) {
// eslint-disable-next-line
return useStore(store, selector, equals);
}
else {
return store;
}
}