Why Is Axios Being Called Twice In My Program
I am trying to set profile state through redux. However for some reason my axios is being called twice my database profile.js const mongoose = require('mongoose'); const Schema = m
Solution 1:
Since I don't have access to your all of your code (and can't debug it), here's a better approach to fetching data. I've structured it closely to what you have and if you follow the working example, you should be able to eliminate the problem.
What I did:
- Renamed
onSubmit={this.onSubmit}
to a more standard declarativethis.handleSubmit
method - Called
this.setState()
in thehandleSubmit
class method to removeselectedOption
value, then in the setState callback, calledgetCurrentProfile(value, history)
(substitute thevalue
with yourtempArray
) - Changed your
<input type="submit" ... />
to a<button type="submit" ... />
- Added a
return
for theaxios.get(...)
call (I've also included anasync/await
version ofgetCurrentProfile
which might be easier to understand -- also substitute theaxios.get
call for youraxios.post
call) - Removed
Redirect
and instead placed a redirect inside theaction
creator ashistory.push('/');
(once request has been successfully sent, it'll redirect the user back to "/" -- if error, no redirect) - Always keep your redux state as a 1:1. In other words, if it's an array, then it stays an array (not
null
), if it's a string, it stays a string (notnumber
)...etc. When usingPropTypes,
your app will throw errors if you do not keep this 1:1 pattern. For example, you're initially settingprofile: null
, but then you set it asprofile: [ Object, Object, Object ... ]
. Instead, it should initially be:profile: []
. - When using
PropTypes
, avoid ambiguous types such asobject
orarray
and instead describe how they are structured. - Due to the nature of redux and how you're setting your component up, you don't need to dispatch
setProfileLoading
. You can just update your data and the connected React component will update to reflect the new change. Dispatching two redux actions separately within a short period of time will most likely lead to component flashing (think of it as callingthis.setState()
twice within a second of each other -- it'll cause your component to flash).
Working example: https://codesandbox.io/s/ovjq7k7516
SelectOption.js
importReact, { Component } from"react";
import { connect } from"react-redux";
importPropTypesfrom"prop-types";
import { withRouter } from"react-router-dom";
importSelectfrom"react-select";
import { clearCurrentProfile, getCurrentProfile } from"../actions";
const options = [
{ value: "todos?userId=1", label: "Todos" },
{ value: "comments?postId=1", label: "Comments" },
{ value: "users?id=1", label: "Users" },
{ value: "albums?userId=1", label: "Albums" }
];
classSelectOptionextendsComponent {
state = {
selectedOption: []
};
handleSubmit = e => {
e.preventDefault();
const { getCurrentProfile, history } = this.props;
const { value } = this.state.selectedOption;
this.setState({ selectedOption: [] }, () =>getCurrentProfile(value, history)
);
};
handleChange = selectedOption =>this.setState({ selectedOption });
render = () => (
<divclassName="container"><formonSubmit={this.handleSubmit}><Selectvalue={this.state.selectedOption}onChange={this.handleChange}options={options}
/><divclassName="save-button"><buttontype="submit"className="uk-button uk-button-primary">
Save Preferences
</button></div><divclassName="clear-button"><buttontype="button"onClick={this.props.clearCurrentProfile}className="uk-button uk-button-danger"
>
Reset Preferences
</button></div></form></div>
);
}
exportdefaultconnect(
state => ({ profile: state.profile }),
{ clearCurrentProfile, getCurrentProfile }
)(withRouter(SelectOption));
SelectOption.propTypes = {
clearCurrentProfile: PropTypes.func.isRequired,
getCurrentProfile: PropTypes.func.isRequired,
profile: PropTypes.shape({
profile: PropTypes.arrayOf(PropTypes.object),
profiles: PropTypes.arrayOf(PropTypes.object),
loading: PropTypes.bool
}).isRequired
};
actions/index.js
import axios from"axios";
import { GET_PROFILE, PROFILE_LOADING, CLEAR_CURRENT_PROFILE } from"../types";
//Get current profileexportconstgetCurrentProfile = (preference, history) => dispatch => {
// dispatch(setProfileLoading()); // not needed return axios
.get(`https://jsonplaceholder.typicode.com/${preference}`)
.then(res => {
dispatch({
type: GET_PROFILE,
payload: res.data
});
// history.push("/") // <== once data has been saved, push back to "/"
})
.catch(err =>dispatch({
type: GET_PROFILE,
payload: { err }
})
);
};
//Get current profile (async/await)// export const getCurrentProfile = (preference, history) => async dispatch => {// try {// dispatch(setProfileLoading()); // not needed// const res = await axios.get(// `https://jsonplaceholder.typicode.com/${preference}`// );// dispatch({// type: GET_PROFILE,// payload: res.data// });// // history.push("/") // <== once data has been saved, push back to "/"// } catch (e) {// dispatch({// type: GET_PROFILE,// payload: { e }// });// }// };//Profile LoadingexportconstsetProfileLoading = () => ({ type: PROFILE_LOADING });
//Clear ProfileexportconstclearCurrentProfile = () => ({ type: CLEAR_CURRENT_PROFILE });
reducers/index.js
import { combineReducers } from"redux";
import { CLEAR_CURRENT_PROFILE, GET_PROFILE, PROFILE_LOADING } from"../types";
const initialState = {
profile: [],
profiles: [],
loading: false
};
constprofileReducer = (state = initialState, { type, payload }) => {
switch (type) {
casePROFILE_LOADING:
return {
...state,
loading: true
};
caseGET_PROFILE:
return {
...state,
profile: payload,
loading: false
};
caseCLEAR_CURRENT_PROFILE:
return {
...state,
profile: []
};
default:
return state;
}
};
exportdefaultcombineReducers({
profile: profileReducer
});
Post a Comment for "Why Is Axios Being Called Twice In My Program"