Reputation: 183
I'm trying to use createAsyncThunk for some API calls but I can't seem to get it to work. My normal actions are working, so I must be connecting my component to redux correctly, but there's something different about createAsyncThunk I'm missing. Calling this.props.checkSession() from below does nothing. None of the console.logs inside checkSession are printed an fetch() never hits the server.
AppScreen
import React from 'react';
import { View, Text, ActivityIndicator } from 'react-native';
import { connect } from 'react-redux';
import { checkSession } from './actions';
import { setToken } from './reducer';
class AppScreen extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
console.log("Mounted")
this.props.checkSession();
console.log("Moving on")
if (!this.props.loading && !this.props.auth_token) {
this.props.navigation.navigate('Auth')
}
}
render() {
if (this.props.loading) {
return (
<View style={{ flex: 1 }}>
<ActivityIndicator />
</View>
)
} else {
return (
<View>
<Text>You're in! {this.props.auth_token}</Text>
</View>
)
}
}
}
function mapStateToProps(state) {
return {
user: state.app.user,
auth_token: state.app.auth_token,
loading: state.app.loading,
error: state.app.error
};
}
const mapDispatchToProps = dispatch => {
return {
checkSession: () => dispatch(checkSession),
setToken: token => dispatch(setToken(token))
}
}
export default connect(mapStateToProps, mapDispatchToProps)(AppScreen);
Actions
import { createAsyncThunk } from "@reduxjs/toolkit";
import { API_URL, ENDPOINTS } from "./../constants";
export const checkSession = createAsyncThunk("checkSession", (thunkAPI) => {
console.log("Running")
let body = {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({auth_token: thunkAPI.getState().app.auth_token})
}
console.log("Checking session.")
return fetch(`${API_URL}${ENDPOINTS.CHECK_SESSION}`, body)
.then(response => {
console.log(`API hit: ${response.ok}`)
if (!response.ok) throw Error(response.statusText);
return response.json();
})
.then(json => json);
});
Reducer
import { createSlice } from "@reduxjs/toolkit";
import { checkSession } from "./actions"
const appSlice = createSlice({
name: "app",
initialState: {
loading: true,
auth_token: "",
error: "",
user: {}
},
reducers: {
setToken: (state, action) => {
state.auth_token = action.payload;
state.loading = false;
},
},
extraReducers: {
[checkSession.pending]: state => {
state.loading = true;
},
[checkSession.rejected]: (state, action) => {
state.loading = false;
state.error = action.error.message;
},
[checkSession.fulfilled]: (state, action) => {
state.loading = false;
state.user = action.payload.user;
state.auth_token = action.payload.auth_token;
}
}
});
export const { setToken } = appSlice.actions;
export const appReducer = appSlice.reducer;
Store
import { appReducer } from "./App/reducer";
import { authReducer } from "./Auth/reducer";
import { configureStore, getDefaultMiddleware } from "@reduxjs/toolkit";
const middleware = [
...getDefaultMiddleware(),
]
const store = configureStore({
reducer: {
app: appReducer,
auth: authReducer
},
middleware,
});
export default store;
Upvotes: 1
Views: 829
Reputation: 67577
You're using checkSession
wrong. It should be dispatch(checkSession())
.
That said, you should also be using the "object shorthand" form of mapDispatch
, like this:
const mapDispatch = {checkSession, setToken};
Upvotes: 2