最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to create API utils reusable in Reactjs - Stack Overflow

programmeradmin5浏览0评论

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 + first then 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 return thunks, 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
Add a ment  | 

2 Answers 2

Reset to default 6

I 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})
};
发布评论

评论列表(0)

  1. 暂无评论