I am quite new to React / React Native / Redux so I feel I am doing something wrong.
The problem
I want to show a spinner while an API is called, and an error message once this API call fails. Props are not updating, and so the components don't show the desired message or spinner
The code (only the relevant chunks)
The component
class Home extends Component {
componentWillMount() {
this.props.tokenGet();
}
renderSpinner() {
if (this.props.loading) {
return (
<Spinner size="large" />
);
}
return null;
}
renderMessage() {
if (this.props.message) {
return (
<Text style={{flex: 1, background: red, color: black}}>
{ this.props.message }
</Text>
)
}
return null;
}
render() {
return (
{ this.renderSpinner() }
{ this.renderMessage() }
)
}
}
const mapStateToProps = (state) => {
const { auth } = state;
const {
loading,
token,
message
} = auth || {
loading: false,
token: null,
message: null
};
return {
loading,
token,
message
}
};
export default connect(mapStateToProps, { tokenGet } )(Home);
The action creator
export const tokenGet = () => {
return (dispatch) => {
dispatch({ type: 'TOKEN_GET_START'});
// Perform the actual API call
let requestToken = fetch(apiBaseUrl + "/tokens", {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(.....)
});
Promise
.race([timeout, requestToken])
.then((response) => response.json())
.then((responseJson) => {
... not relevant ...
})
.catch((error) => {
dispatch({ type: 'TOKEN_GET_FAIL', payload: error});
});
The timeout function, which gets called when the server fails to respond
let timeout = new Promise((resolve, reject) => {
setTimeout(reject, 2000, 'Request timed out. Please check your internet connection.');
});
The reducer
import {
TOKEN_GET_START,
TOKEN_GET_SUCCESS,
TOKEN_GET_FAIL
} from '../actions/types';
const INITIAL_STATE = {
loading: false,
token: null,
message: null
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case TOKEN_GET_START:
return { ...state, loading: true };
case TOKEN_GET_SUCCESS:
return { ...state, loading: false, token: action.payload };
case TOKEN_GET_FAIL:
return { ...state, loading: false, message: action.payload };
default:
return state;
}
};
The combined reducers
import { combineReducers } from 'redux';
import AuthReducer from './AuthReducer';
export default combineReducers({
auth: AuthReducer
});
The actual behavior is that the props don't change and no message or spinner is visible. With some console logs I know that the API call ends because of the timeout. I am not sure if the state gets updated properly though. I don't know in at which point I can console log this.
It turned out to be because of the quotes in 'TOKEN_GET_FAIL'
That is a string and not the const
I need. So I changed to TOKEN_GET_FAIL
and it works.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.