Я использую ловушку возврата useMemo и фильтрую массив элементов. Затем у меня есть функция переключения, которая переключает, является ли элемент истинным или ложным, а затем отправляет этот элемент обратно в API, если он является истинным или ложным, и добавляет его в список. Внутри функции, которая использует хук useReducer, массив находится на один шаг позади. Например, возвращается массив элементов, и вы переключаете, продаются ли они в продаже или нет, а если вы переключаете true, они добавляются в saleList, а если они переключаются в не для продажи, они добавляются в notSaleList. В функции длина saleList вернется к 3, но на самом деле это 4, затем вы удаляете дом, чтобы сделать его 3, но он вернет 4. Кто-нибудь знает, почему это было бы спасибо?
const homesReducer = (state, action) => {
switch (action.type) {
case 'FETCH_INIT':
return {
...state,
isLoading: true,
isError: false,
};
case 'FETCH_SUCCESS':
//action.payload to object
const entities = action.payload.reduce((prev, next) => {
return { ...prev, [next.Id]: next };
}, {});
return {
...state,
isLoading: false,
isError: false,
homes: entities,
};
case 'FETCH_FAILURE':
return {
...state,
isLoading: false,
isError: true,
};
case 'TOGGLE_SALE_HOME_INIT':
return {
...state,
homes: {
...state.homes,
// ask Jenkins
[action.payload]: {
...state.homes[action.payload],
IsSaleHome: !state.homes[action.payload].IsSaleHome,
},
},
};
case 'TOGGLE_SALE_HOME_SUCCESS':
return {
...state,
};
case 'TOGGLE_SALE_HOME_FAILURE':
// TODO update back if failed
return {
...state,
homes: {
...state.homes,
// ask Jenkins
[action.payload]: {
...state.homes[action.payload],
IsSaleHome: !state.homes[action.payload].IsSaleHome,
},
},
};
default:
return { ...state };
}
};
const useOnDisplayApi = activeLotNumber => {
const [state, dispatch] = useReducer(homesReducer, {
isLoading: false,
isError: false,
homes: [],
saleHomes: [],
});
const homes = useMemo(() => {
return Object.keys(state.homes).map(id => {
return state.homes[id];
});
}, [state.homes]);
}
const saleHomes = useMemo(() => {
return homes.filter(home => {
return home.IsSaleHome;
});
}, [homes]);
const notSaleHomes = useMemo(() => {
return homes.filter(home => {
return !home.IsSaleHome && !home.IsSuggestedSaleHome;
});
}, [homes]);
const toggleSaleHome = async (home, undo = true) => {
dispatch({ type: 'TOGGLE_SALE_HOME_INIT', payload: home.Id });
try {
const didUpdate = await updateInventory(
activeLotNumber,
home.InventoryId,
{
InventoryId: home.InventoryId,
IsSaleHome: !home.IsSaleHome,
}
);
if (didUpdate == true) {
dispatch({ type: 'TOGGLE_SALE_HOME_SUCCESS' });
}
else {
dispatch({ type: 'TOGGLE_SALE_HOME_FAILURE', payload: home.Id });
}
} catch (error) {
setTimeout(() => {
dispatch({ type: 'TOGGLE_SALE_HOME_FAILURE' });
}, 600);
}
};