I'm a beginner in ReactJS, and I'm trying to improve the writing of my codes, and I ended up getting to the API calls part, I want to improve the reusability of my API calls and set them with a specific folder something like utils / APIcalls.js but I do not know the best way and the correct way to do this, I have the following API call getItems()
:
Home.jsx
export default class Home extends Component {
constructor(props) {
super(props);
this.state = {
'items': [],
isLoading: false,
error: null,
};
}
ponentDidMount() {
this.getItems()
this.refresh = setInterval(() => this.getItems(), 100000);
}
ponentWillUnmount() {
clearInterval(this.refresh)
}
getItems() {
this.setState({ 'isLoading': true });
fetch('https://xxx/api/article/')
.then(results => {
if (results.ok) {
return results.json();
} else {
throw new Error('Something went wrong ...');
}
})
.then(results => this.setState({ 'items': results, 'isLoading': false }))
.catch(error => this.setState({ error, isLoading: false }));
}
render() {
const { isLoading, error } = this.state;
if (error) {
return <p>{error.message}</p>;
}
if (isLoading) {
return <Loading />
}
return (
<div className="container" >
<div className="row align-items-start">
<Principal items={this.state.items} />
</div>
<hr />
<div className="row align-items-start">
<Secondary items={this.state.items} />
</div>
</div>
);
}
}
I use the same call in multiple places, is there any way to set these calls globally, and call them more easily elsewhere in the code?
To solve this problem problem I used axios to create reusable functions:
I created a folder called by utils, inside that folder I created a file called by apiConfig.js and apiCalls.js:
import API from './apiConfig'
export default {
getArticles: () => {
return API.get('article')
.then(res => res.data)
},
getUser: () => {
return API.get('user')
.then(res => res.data)
}
}
After that, I call that functions in the ponents using that way:
ponentDidMount() {
this.getItems()
}
getItems() {
this.setState({ 'isLoading': true });
API.getArticles().then(items => this.setState({ items, 'isLoading': false }))
.catch(error => this.setState({ error, isLoading: false }));
}
I'm a beginner in ReactJS, and I'm trying to improve the writing of my codes, and I ended up getting to the API calls part, I want to improve the reusability of my API calls and set them with a specific folder something like utils / APIcalls.js but I do not know the best way and the correct way to do this, I have the following API call getItems()
:
Home.jsx
export default class Home extends Component {
constructor(props) {
super(props);
this.state = {
'items': [],
isLoading: false,
error: null,
};
}
ponentDidMount() {
this.getItems()
this.refresh = setInterval(() => this.getItems(), 100000);
}
ponentWillUnmount() {
clearInterval(this.refresh)
}
getItems() {
this.setState({ 'isLoading': true });
fetch('https://xxx/api/article/')
.then(results => {
if (results.ok) {
return results.json();
} else {
throw new Error('Something went wrong ...');
}
})
.then(results => this.setState({ 'items': results, 'isLoading': false }))
.catch(error => this.setState({ error, isLoading: false }));
}
render() {
const { isLoading, error } = this.state;
if (error) {
return <p>{error.message}</p>;
}
if (isLoading) {
return <Loading />
}
return (
<div className="container" >
<div className="row align-items-start">
<Principal items={this.state.items} />
</div>
<hr />
<div className="row align-items-start">
<Secondary items={this.state.items} />
</div>
</div>
);
}
}
I use the same call in multiple places, is there any way to set these calls globally, and call them more easily elsewhere in the code?
To solve this problem problem I used axios to create reusable functions:
I created a folder called by utils, inside that folder I created a file called by apiConfig.js and apiCalls.js:
import API from './apiConfig'
export default {
getArticles: () => {
return API.get('article')
.then(res => res.data)
},
getUser: () => {
return API.get('user')
.then(res => res.data)
}
}
After that, I call that functions in the ponents using that way:
ponentDidMount() {
this.getItems()
}
getItems() {
this.setState({ 'isLoading': true });
API.getArticles().then(items => this.setState({ items, 'isLoading': false }))
.catch(error => this.setState({ error, isLoading: false }));
}
Share
Improve this question
edited Nov 5, 2023 at 23:00
Brian Tompsett - 汤莱恩
5,89372 gold badges61 silver badges133 bronze badges
asked Nov 5, 2018 at 23:02
Jefferson BruchadoJefferson Bruchado
9183 gold badges17 silver badges34 bronze badges
5
-
4
You can extract
fetch
+ firstthen
to a separate function and use it here – Volodymyr Commented Nov 5, 2018 at 23:06 - 1 How would I extract it? would separate into another folder only with api calls? what would the folder structure look like? – Jefferson Bruchado Commented Nov 5, 2018 at 23:10
-
It is pletely up to you - as far as you are fortable using it. I would suggest to create one file (
/api/index.js
) if there is not a huge number of such functions (up to 10-15). If there are more - try to group them somehow (for example domain-drivenly -/api/user.js
,/api/products.js
, etc) – Volodymyr Commented Nov 5, 2018 at 23:14 -
i like API calls to go in
actions
that returnthunks
, although I may be biased because that's the structure I learned initially with react/redux – HolyMoly Commented Nov 5, 2018 at 23:16 - 1 As stated in the ments it is much your own preferences that decide where you want the function to go in your folder structure. Maybe you don't even need a new separate folder if it's just one function. The main goal is to separate out the fetch into a reusable function and then put it in a file where you think it suits your needs and structure of the code best. One more thing you can do is to turn your fetch function into a higher order function. That way you can pass in a function as an argument. That argument function will calculate what to return from the fetch function. Flexible ;) – weibenfalk Commented Nov 5, 2018 at 23:24
2 Answers
Reset to default 6I agree with all the ments, your './utils/API.js' would look like this:
export default {
getItems: () => {
return fetch('https://xxx.api/article')
.then(res => res.json());
},
otherApiCall: (params) => {
}
}
The ponent like so:
import API from '../utils/API';
ponentDidMount() {
const items = API.getItems();
this.setState({ items });
}
Wherever you import it, this call should result in your items, you can add error handling here or in the ponent. As HolyMoly mented, in Redux-Thunk I usually handle this in the actions (where the call is sent)
In my opinion, I usually used these.
API/Axios_Api.js
import axios from 'axios';
const MYAPI= "YOUR API"
export const AXIOS_API = () => {
axios.get(MYAPI)
.then( res => res.data )
.catch (err => thorw{err})
};