使用fetch包装器解决绑定问题

时间:2018-04-30 23:10:24

标签: reactjs

新的反应用户在这里。我正在尝试为fetch()方法创建自定义包装器:

/**
 * Custom fetch() wrapper
 *
 * @param options {object} - options for request
 *
 **/

export const Ajax = (options) => {

    const defaultOptions={
        url:"",
        method:"get",
        onSuccess:function(json){
            console.log("Default success handler. ", json)
        },
        onError:function(error){
            console.log("Default error handler", error);
        },
        onStart:function(){

        },
        onComplete:function(){

        }
    };

    const mergedOptions = {...defaultOptions, ...options};
    mergedOptions.onStart();

    return () => fetch(mergedOptions.url, {
        credentials: 'include'
    })
        .then((response) =>  {
            if (!response.ok) {
                throw response;
            }
            return response;
        })
        .then((response) => response.json())
        .then((responseJson) => {
            mergedOptions.onSuccess(responseJson);
            mergedOptions.onComplete();
        })
        .catch((error) => {
            mergedOptions.onError(error);
            mergedOptions.onComplete();
        });
};

export default Ajax;

我这样称呼它:

import React, { Component } from 'react';
import Ajax from '../../functions/Ajax.jsx';

class SinglePageContainer extends Component{


    fetchData(){
        let url="/data-url";

        return Ajax({
            url:url,
            onStart:function(){
                this.setState({loading:true});
            },
            onComplete:function(){
                this.setState({loading:false});
            },
            onSuccess:function(json){
                this.setState({ajaxData:json.data});
            }

        }).bind(this);


    }

    constructor(props){
        super(props);
        this.state = {
            loading:true,
            error:false
        };
    }
    componentDidMount(){
        this.fetchData();
    }
}

export default SinglePageContainer;

运行时,我收到错误this.setState is not a function for Object.onStart()

因此onStart()被调用,但SinglePageContainer没有约束力。如何将其绑定到参数对象?我使用Ajax({options}).bind(this);但没有运气。

1 个答案:

答案 0 :(得分:1)

您需要为onStartonCompleteonSuccess函数调用bind,如下所示:

fetchData(){
    let url="/data-url";

    return Ajax({
        url:url,
        onStart:function(){
            this.setState({loading:true});
        }.bind(this),
        onComplete:function(){
            this.setState({loading:false});
        }.bind(this),
        onSuccess:function(json){
            this.setState({ajaxData:json.data});
        }.bind(this)
    });
}

或者您可以使用Arrow functions

 fetchData(){
    let url="/data-url";

    return Ajax({
        url: url,
        onStart: () => {
            this.setState({ loading:true });
        },
        onComplete: () => {
            this.setState({ loading:false });
        },
        onSuccess: (json) => {
            this.setState({ ajaxData:json.data });
        }
    });
}

您现在正在做的是您在fetch包装器中绑定this,这对您传递给此函数的对象没有影响。