显示使用Axios和React加载Spinner(可能是Redux)

时间:2019-05-31 14:18:08

标签: reactjs redux react-redux axios

我的目标是显示在调用http请求时的加载微调器。我想在全局范围内执行此操作,这意味着,当任何组件调用某个api时,自动显示微调框,最好没有附加代码来控制微调框。

我正在使用react和axios。我知道axios的拦截器。

我的实际结构:

<Component App>
    <Component A />
    <Component B />
    <Loading Component>
</Component App>

我不知道是否有可能做出反应,但是我试图制作一个通用类来实现有关该服务的基本信息,例如baseUrl和http拦截器。因此,当需要调用API服务时,我使用通用类创建一个专门的类,并从那里集中了所有api方法,然后使用基类调用axios方法get,post等。因此,拦截器出现并在请求之前显示微调框,在请求之后隐藏。

这个想法是组件调用专门的类来调用API并显示微调框,直到请求运行为止。

我认为可以使用redux来使状态成为全局状态,但是我不知道是否可以在类(API类库和专用API类)中实现

我的问题: -是否可以使用此架构? -如果是,该如何实现和使用redux? -IIs是否有权使用类或更好地使用组件来实现基本服务类和专用类?

应用程序组件:

class App extends Component {

  constructor(props) {
      super(props);

      this.state = {
          rows: []
      };
  }

  componentDidMount() {
var service = new specializedService();

     var response = 

 specializedService.someAPIMethod(1).then((res) => {
           this.setState({
               rows: res.data
           });
     });
}

render() {
return (
        <div className="App">
                <Component A rows={this.state.rows} />
                <Component B rows={this.state.rows}/>
                <Loading />
        </div>
    );
  }

specializedService:

import serviceBase from "./serviceBase";

class specializedService {

    someAPIMethod(id) {
        return serviceBase.get('someMethod/' + id);
    };

}

serviceBase:

import axios from "axios";

const serviceBase = () => {

    const api = axios.create({
        baseURL: 'https://xxxxx.xxxxx.com/xxxxxx/'
    });

    api.interceptors.request.use(async (config) => {
        try{
            // In this moment, show the spinner
            // showLoading();
        }
        catch(e)
        {
            alert('Error request' + e);
        }

        return config;
    });

    api.interceptors.response.use(async (config) => {
        try {
            // In this moment, hide the spinner
            // hideLoading();
        }
        catch(e)
        {
            alert('Error response' + e);   
        }

        return config;
    });

    return api;
};

export default serviceBase;

3 个答案:

答案 0 :(得分:0)

您可以尝试使用here和共享方法来更改Loading组件的可见性。

答案 1 :(得分:0)

我认为实现这一目标的最佳方法是使用redux。您可以使用某种“请求状态”简化程序,并在商店中使用一个值来指示是否正在发送请求。

伪代码:

const sendRequest = async (req) {
  dispatch({type: "REQUEST_SENT"});
  const res = await axios.get(req);
  dispatch({type: "REQUEST_SUCCEEDED", payload: res});
}

根据操作,您可以在商店中切换请求状态的值,从而重新呈现组件。

答案 2 :(得分:0)

使用redux和thunk非常方便。

但是,您可以使用类似的技巧,

this.state = {
 rows: [],
 isLoading: false,
}

apiCallFunction = () => {

 this.setState(prevState => ({ isLoading: !prevState.isLoading }) // to be true..

 // api call..
 // upon response success => 
 this.setState(prevState => ({
   isLoading: !prevState.isLoading, // to be false..
   rows: prevState.rows = response json,
 })
}

和渲染中

render () {
 return (
  {isLoading && <Spinner />}
  {... handle the rest} 
 )
}