This is not a complex app, I am just trying to better understand Promises and how they work, so I made this simple app with React and Redux, its only one button, when I press the button I want to dispatch an action to the redux store. I want to simulate a really slow api, so inisde my asyncthunk I've created a promise and inside a settimeout. When I press the button I want to see my promise pending for 2 seconds and after this time I want to se my promise fulfilled, I am checking this using the Redux Chrome extension, but my promise is eternally pending.
app.js
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import { useDispatch } from 'react-redux';
import './App.css';
const cargar = createAsyncThunk(
"cargar/data",
async () => {
let respuesta;
await new Promise((resolve) => {
setTimeout(() => respuesta = resolve, 2000);
});
return respuesta;
}
)
const cargaSlice = createSlice({
name: "cargar",
initialState: {
isLoading: false,
loaded: false,
hasError: false
},
extraReducers: (builder) => {
builder.addCase(cargar.pending, (state, action) => {
state.isLoading = true;
state.loaded = false;
state.hasError = false;
})
.addCase(cargar.fulfilled, (state, action) => {
state.isLoading = false;
state.loaded = action.payload;
state.hasError = false;
})
.addCase(cargar.rejected, (state, action) => {
state.isLoading = false;
state.loaded = false;
state.hasError = true;
})
}
})
export default cargaSlice.reducer;
export function App() {
const dispatch = useDispatch();
const handleCarga = () => {
dispatch(cargar());
}
return (
<div className="App">
<h1>Presiona el botón para cargar</h1>
<button onClick={handleCarga}>Cargar</button>
</div>
);
}
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { App } from './App';
import reportWebVitals from './reportWebVitals';
import reducer from './App';
import { configureStore } from '@reduxjs/toolkit';
import { Provider } from 'react-redux';
const store = configureStore({
reducer: reducer
})
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);
CodePudding user response:
Your resolve
function is never called, try this:
const cargar = createAsyncThunk(
"cargar/data",
() => new Promise((resolve) => setTimeout(resolve, 2000))
);
CodePudding user response:
OK I did solve it, still I am not sure if I fully understand promises so if someone can comment wheter I am rigth or wrong with my conclusions that would be apreciated. So here is the thing, the resolve inside my promise it is a callback (or at least I think so) so that resolve is the first argument of my settimeout and no other stuff, then my Promise is really not build to return anything and settimeout doesnt return anything either, so returning my Promise will allways lead to an unwanted undefined. Here is the working code, I hope it will be usefull for someone:
const cargar = createAsyncThunk(
"cargar/data",
async () => {
let respuesta = undefined; // this value can be anything really
await new Promise((resolve) => {
setTimeout(resolve, 2000);
respuesta = true;
});
return respuesta;
}
)