Tengo una aplicación que realiza acciones de API cuando se presionan los botones. Cuando finaliza la acción, actualizo un estado de retroceso. Pero la cuestión es que cuando trato de actualizar el estado, reemplazo el anterior con el nuevo actualizado, y en un contexto asíncrono no sé cómo obtener el estado actual en el momento en que se ejecuta mi código.
const [tasks, setTasks] = useRecoilState(tasksState); const handleAction = async (task: Task): Promise<void> => { try { // some async stuff here with an API // update the recoil state here // MY ISSUE HERE is that the "tasks" state is not the one at the moment where the code is executed after the API response, // but at the moment where handleAction has been called... // So I can override the state with old values, previously updated from an other handleAction ended earlier. const newTasks = updateTasks(tasks, anOtherParameterFromApiResponse); setTasks(newTasks); } catch(error){ console.log("error: ", error); } }¿Me puede explicar cómo abordar dicho patrón y poder actualizar el estado cuando finalicen mis acciones asincrónicas?
Nota: mi estado es una matriz de objetos, y mi función updateTasks() es una función que actualiza un objeto de esta matriz para que pueda actualizar el estado con esta matriz calculada.
¡Gracias de antemano por la valiosa ayuda que me brindará!
He encontrado una solución por mí mismo:
Creé un 'selector' a partir de mis tareas 'átomo' y delegué en un método de 'conjunto' personalizado la agregación del nuevo objeto con el estado de la matriz de objetos. Gracias al método 'get' provisto en el parámetro, puedo acceder al estado actualizado de la matriz de objetos.
selectores.ts:
/** * Allow to update the tasksState by passing in parameter the task to update * That way we can call this from an async context and updating value by agreagating to the eventual new ones */ export const taskUnitUpdaterSelector = selector<Task>({ key: "taskUnitUpdaterSelector", get: () => { throw new Error("Not implemented !"); }, set: ({ get, set }, newTask: Docker) => { const tasks = get(tasksState); // remove from tasks list the new one updated to add it then const tasksCloneWithoutNewUpdatedOne = tasks.filter( (t) => !(t.name === newTask.name && t.server === newTask.server), ); const newTasks = [...tasksCloneWithoutNewUpdatedOne , newTask]; set(tasksState , newTasks); });componente.ts
const taskUnitUpdater = useSetRecoilState(taskUnitUpdaterSelector); const handleAction = async (task: Task): Promise<void> => { try { // some async stuff here with an API // the new tasks array is computed inside the selector set function to be able to access to up to date data ! taskUnitUpdater(newTask ); } catch(error){ console.log("error: ", error); } }