Обновление триггера реактивной переменной клиента Apollo только один раз
Я создаю веб-приложение, которое управляет водозаборными скважинами, используя клиент React и Apollo с сервером graphQl (HASURA). Чтобы сохранить изменения пользователей каждого поля в каждой таблице, которая будет отправлена на сервер graphQl, я реализовал реактивную переменную для управления историей изменений полей.
Структура объекта, содержащего эти изменения, выглядит следующим образом:
{
tableName: {
id_of_the_feature:{
//THIS MAP CONTAINS THE HISTORY OF MODIFICATION OF THE FIELDS
Map<number, field-state>
}
}
}
Мой файл кеша выглядит так
export const dataStateVar = makeVar({});
export const cache = new InMemoryCache({
typePolicies: {
Query: {
fields: {
dataState: {
read() {
console.log(dataStateVar());
return dataStateVar();
},
},
},
},
},
});
Затем у меня есть хук, который управляет dataStateVar, который выглядит как
export const useDataState = () => {
const GET_DATA_STATE = gql`
query {
dataState @client
}
`;
let {
data: { dataState: state },
} = useQuery(GET_DATA_STATE);
const getState = (tableName: string, id: number | null) => {
if (!state[tableName]) {
const newState = { ...state };
newState[tableName] = { selectedItems: [] };
dataStateVar(newState);
state = newState;
}
if (id && !state[tableName][id]) {
const newState = { ...state };
const tableState = { ...newState[tableName] };
tableState[id] = new Map<number, any>();
newState[tableName] = tableState;
dataStateVar(newState);
state = newState;
}
return [{ ...state }, { ...state[tableName] }];
};
return [getState];
};
const saveTableState = (tableName: string, oldState: any, newTableState: any) => {
const newState = { ...oldState };
newState[tableName] = newTableState;
// 1) SAVE STATE OBJECT CLIENT DATA
dataStateVar(newState);
};
export const useHistoryState = (tableName: string, id: number) => {
const [getState] = useDataStateNew();
const addHistoryItem = (newItemState) => {
// 1) GET LIST OBJECT FROM STATE
const [state, tableState] = getState(tableName, id);
// 2) ADD THE STATE TO THE LIST
const itemStateHistory: Map<number, any> = tableState[id];
const keys = Array.from(itemStateHistory.keys());
const lastKey = keys.pop() || 0;
tableState[id] = itemStateHistory.set(lastKey + 1, newItemState);
// 3) SAVE STATE OBJECT CLIENT DATA
saveTableState(tableName, state, tableState);
};
const setOriginalHistoryItem = (originalState) => {
// 1) GET LIST OBJECT FROM STATE
const [state, tableState] = getState(tableName, id);
// 2) SET THE ORIGINAL STATE TO STATE HISTORY
const itemStateHistory: Map<number, any> = tableState[id];
tableState[id] = itemStateHistory.set(0, originalState);
// 3) SAVE STATE OBJECT CLIENT DATA
saveTableState(tableName, state, tableState);
};
const getLastItem = () => {
// 1) GET LIST OBJECT FROM STATE
const [, tableState] = getState(tableName, id);
// 2) RETURN THE LAST ELEMENT OF THE ARRAY
return Array.from(tableState[id].values()).pop();
};
return {
addHistoryItem,
setOriginalHistoryItem,
getLastItem,
};
};
есть компоненты, в которых, когда пользователь меняет свои значения, функция addHistoryItem. Когда я изменяю поле в первый раз, вызывается addHistoryItem, обновляю состояние, и все работает нормально. Во второй раз, когда я меняю поле, вызывается функция addHistoryState (), новое состояние сохраняется, но это обновление не запускает перезагрузку значения, переданного через getLastItem (), и компонент пользовательского интерфейса возвращается к предыдущему ценить.
const NULL_VALUE = { value: '', label: '' };
export default function AutoCompleteComponent({
options,
field,
tableName,
featureId,
}) {
const theme = useTheme();
const classes = useStyles(theme);
const { addStateItem, getStateItem } = useHistoryState(tableName, featureId);
let stateItem = { ...getStateItem() };
const stateValue = stateItem[field.columnName] || NULL_VALUE;
options.push(NULL_VALUE);
// handle on change of properties
const handleChange = (event, newValue) => {
// CHECK IF NEW VALUE IS PRESENT
if (!newValue) return;
// SET THE DATA STATE
stateItem = { ...stateItem };
stateItem[field.columnName] = newValue;
addStateItem(stateItem);
};
return (
<div classeName={classes.fieldWrapper}>
<Autocomplete
className={classes.autoComplete}
id="combo-box-demo"
value={stateValue}
options={options}
onChange={handleChange}
disabled={!isOnEdit}
getOptionLabel={(option) => option.label}
renderInput={(params) => (
<TextField {...params} label={field.label} margin="normal" />
)}
/>
</div>
);
}
почему это происходит и какое возможное решение для внесения изменений, внесенных триггерами функции addHistoryState, повторно отображает более одного раза?