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.handleSubmitmethod - Called
this.setState()in thehandleSubmitclass method to removeselectedOptionvalue, then in the setState callback, calledgetCurrentProfile(value, history)(substitute thevaluewith yourtempArray) - Changed your
<input type="submit" ... />to a<button type="submit" ... /> - Added a
returnfor theaxios.get(...)call (I've also included anasync/awaitversion ofgetCurrentProfilewhich might be easier to understand -- also substitute theaxios.getcall for youraxios.postcall) - Removed
Redirectand instead placed a redirect inside theactioncreator 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 asobjectorarrayand 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"