5

In my react JS app, I make many API calls,

Rather than having to specify: const BASE_URL = 'https://apiurlgoeshere.com/'

on every page, I'd rather have BASE_URL accessible throughout the entire application, so I can just do BASE_URL + API_CALL for example

James Lock
  • 185
  • 3
  • 10
  • Did you try to use `localStorage` to save global variable? – Julian Dec 06 '18 at 12:07
  • @Jin — It's a SPA, there's no need to store it. – Quentin Dec 06 '18 at 12:08
  • I would suggest providing all URLs in single page and then use that urls into different pages – Just code Dec 06 '18 at 12:08
  • okay then please try to do like this. window.BASE_URL = 'https://apiurlgoeshere.com/'; Then you can use this variable globally. – Julian Dec 06 '18 at 12:09
  • Assuming you're using a module bundler like Webpack, create a module (e.g. `constants.js`) and import it wherever you need the constants. – Joe Clay Dec 06 '18 at 12:09
  • Possible duplicate of [How to declare a global variable in React?](https://stackoverflow.com/questions/34351804/how-to-declare-a-global-variable-in-react) – Quentin Dec 06 '18 at 12:10
  • If this is a `create-react-app`-generated project, I suppose you could store things like that in files such as `config.js` containing `export const BASE_URL = 'https://api.example.com'` and import it in your component(s). There are many solutions to this however... – ionizer Dec 06 '18 at 12:13

4 Answers4

9

If this is just adding BASE_URL, then this can be achieved by declaring it inside a constants.js file and exporting it from there. But then, that makes us do BASE_URL + "something" each time we make a network request which isn't really ideal either. Also there might be some scenarios where other configuration have to be shared, like say, a common header that has to be added to all the requests.

To solve this, most request libraries have in-build solutions. If we are choosing axios as the most popular one, we can create a instance like:

const instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});
export default instance;

and import this everywhere the axios is going to be used like:

import axios from "./axios-instance";

assuming axios-instance.js is the file where the instance is created. Now you can skip adding the BASE_URL to every request as it is already provided in the instance.

Agney
  • 18,522
  • 7
  • 57
  • 75
  • Looks interesting and probably better than React Context. Can you elaborate when you use React Context and when to use this way? – Eres Jul 07 '20 at 19:15
  • @EresDev: when React Context is [an over-engineered solution](https://dev.to/bhldev/comment/1222i). – Dan Dascalescu Jul 14 '20 at 23:07
1

If webpack is being used for code bundle, DefinePlugin can be used.

new webpack.DefinePlugin({
    'BASE_URL': JSON.stringify('https://apiurlgoeshere.com/')
});

For gulp build, gulp-replace can be used.

.pipe(replace('BASE_URL', 'https://apiurlgoeshere.com/'))

sumana
  • 21
  • 4
0

I know it's been a while since I created this post - just wanted to go through what I've learnt really.

It's a great way to set a global config for Axios. I typically create a folder and create an api.js file within it which I use to make all of my API calls, this is great as it means you only have to specify headers / base URL / credentials etc once.

James Lock
  • 185
  • 3
  • 10
0

Here is a code example for a solution:

function apiCall (method, path, data) {
    let url = "https://urltoyourapis.com/";
    return new Promise((resolve, reject) => {
        return Axios[method](url, {headers}, data).then(res => {
            return resolve(res);
        }).catch(err => {
            return reject(err);
        })
    })
}

Now, whenever you want to make an API call you'd import this function into the file where you would like to make the API call and do the following:

apiCall("get", "account-info")

This will then make an API call to the endpoint "account-info" to get the information, you can either await and set the result to a variable or use .then .catch to handle the response.

James Lock
  • 185
  • 3
  • 10