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
- 1827 reads