react Пример обработчика сложных состояний формы, вложенных массивов объектов (с использованием immer)
Primary tabs
Пример хелпера, который определяет обработчики полей и также функцию изменения и получения состояния (функция получение в отличии от объекта стейта не меняется и её оказывается предпочтительнее использовать в зависимостях колбека при мемоизации):
import React from 'react'; import dot from 'dot-object'; import produce from "immer"; /** * * @param {objecr} formState * @param {function} setFormState * @param {object} settings пример: * {defaultStates: // отвечает за добавление значений в массив * {phoneNumber: {....}, contact: {...}} * } */ function FromStateHelper(initialState, settings) { const { current: it } = React.useRef({}); const reducer = React.useMemo(() => { const innerProduce = produce((formState, action) => { const { type, evt } = action; // console.log('test value', evt && evt.target.value); switch (type) { case 'handleChangeText': dot.str(evt.target.name, evt.target.value, formState); break; case 'handleChangeInt': dot.str(evt.target.name, parseInt(evt.target.value), formState); break; case 'handleChangeBool': console.log('handleChangeBool', evt.target.name); dot.str(evt.target.name, (evt.target.value === 'true'), formState); break; case 'handlePushDefaultElementInArray': { if (typeof evt.preventDefault === "function") { evt.preventDefault(); } let arr = dot.pick(evt.target.name, formState); arr.push({ ...settings.defaultStates[evt.target.dataset['stateName']] }); break; } case 'handleRemoveElementFromArray': { if (typeof evt.preventDefault === "function") { evt.preventDefault(); } let arr = dot.pick(evt.target.name, formState); arr.splice(evt.target.dataset['arrayIndex'], 1); break; } case 'setState': return action.state; } }); return function innerREducer(...args) { return innerProduce(...args); } }, [settings]); const [formState, dispatch] = React.useReducer(reducer, initialState); // console.log(formState) const handleChangeBool = React.useCallback((evt) => { dispatch({ type: 'handleChangeBool', evt: evt.nativeEvent }); }, [dispatch]); const handleChangeText = React.useCallback((evt) => { //window.testValue = 'test value'; dispatch({ type: 'handleChangeText', evt: evt.nativeEvent }); window.testValue = null; }, [dispatch]); const handleChangeInt = React.useCallback((evt) => { dispatch({ type: 'handleChangeInt', evt: evt.nativeEvent }); }, [dispatch]); const handlePushDefaultElementInArray = React.useCallback((evt) => { dispatch({ type: 'handlePushDefaultElementInArray', evt: evt.nativeEvent }); }, [dispatch]); const handleRemoveElementFromArray = React.useCallback((evt) => { dispatch({ type: 'handleRemoveElementFromArray', evt: evt.nativeEvent }); }, [dispatch]); const setFormState = React.useCallback(state => { dispatch({ type: 'setState', state }); }, [dispatch]); const getFormState = React.useCallback(state => { return it.formState; }, []); Object.assign(it, { getFormState, formState, setFormState, handleChangeBool, handleChangeText, handleChangeInt, handlePushDefaultElementInArray, handleRemoveElementFromArray, }); return it; } export default FromStateHelper;
- Log in to post comments
- 1416 reads