前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >react: 怎么优雅使用获取数据

react: 怎么优雅使用获取数据

作者头像
西南_张家辉
发布2021-02-02 10:10:37
发布2021-02-02 10:10:37
1.6K00
代码可运行
举报
文章被收录于专栏:张家辉的树屋张家辉的树屋
运行总次数:0
代码可运行

写在最前面

  • 适用于 react 初学者,需要了解怎么优雅的处理获取数据操作。
  • loading 和 error 逻辑怎么处理?
  • 使用 Promises 和 Async/Await, 高阶组件获取数据?

怎么优雅的使用 react 获取数据

  • 普通刚开始学习 react 的初学者都会有一个问题,我们需要展示一列数据。但是我们需要在 react 的生命周期(lifecycle)中哪里去获取这个数据合适啦?
  • 现在我们知道 componentDidMount 在生命周期中

使用 JavaScript Promises 去处理数据

  • componentDidMount() 使用 promise
代码语言:javascript
代码运行次数:0
运行
复制
import React, { Component } from 'react';

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      data: null,
    };
  }

  componentDidMount() {
    fetch('https://api.mydomain.com')
      .then(response => response.json())
      .then(data => this.setState({ data }));
  }

  ...
}

export default App;
复制代码

当然我们可以使用第三方 api,当我们获取数据成功以后。然后就被存储到了 react 的 this.setState() 方法中。然后render()会重新渲染,然后我们就可以看到我们的数据展示了。

代码语言:javascript
代码运行次数:0
运行
复制
...

class App extends Component {
 ...

  render() {
    const { hits } = this.state;

    return (
      <ul>
        {hits.map(hit =>
          <li key={hit.objectID}>
            <a href={hit.url}>{hit.title}a>
          li>
        )}
      ul>
    );
  }
}

export default App;
复制代码

note: 如果你想了解最新的 react hooks 来获取处理数据的方法:https://www.robinwieruch.de/react-hooks-fetch-data/

怎么优雅的处理 loading 和 error?

  • 一般在获取数据的时候我们需要处理几种情况,加载中 loading,出错 error,加载成功。所以一般情况下我们会把 loading 和 error 状态存在 state 中。
loading 加载中处理
代码语言:javascript
代码运行次数:0
运行
复制
...

class App extends Component {
  constructor(props) {
    super(props);

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

  componentDidMount() {
    this.setState({ isLoading: true });

    fetch(API + DEFAULT_QUERY)
      .then(response => response.json())
      .then(data => this.setState({ hits: data.hits, isLoading: false }));
  }

  ...
}

export default App;
复制代码
  • 使用一个 Loading 的提示
代码语言:javascript
代码运行次数:0
运行
复制
...

class App extends Component {
  ...

  render() {
    const { hits, isLoading } = this.state;

    if (isLoading) {
      return <p>Loading ...p>;
    }

    return (
      <ul>
        {hits.map(hit =>
          <li key={hit.objectID}>
            <a href={hit.url}>{hit.title}a>
          li>
        )}
      ul>
    );
  }
}
复制代码
Error 处理
  • 初始化 error
代码语言:javascript
代码运行次数:0
运行
复制
...

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      hits: [],
      isLoading: false,
      error: null,
    };
  }

  ...

}
复制代码
  • 当我们使用 promise 的使用,使用 catch() 去捕捉错误。
代码语言:javascript
代码运行次数:0
运行
复制
...

class App extends Component {

  ...

  componentDidMount() {
    this.setState({ isLoading: true });

    fetch(API + DEFAULT_QUERY)
      .then(response => response.json())
      .then(data => this.setState({ hits: data.hits, isLoading: false }))
      .catch(error => this.setState({ error, isLoading: false }));
  }

  ...

}
复制代码
  • react 原生的API 不能处理一些错误的状态码,这里需要手动处理一下。
代码语言:javascript
代码运行次数:0
运行
复制
...

class App extends Component {

  ...

  componentDidMount() {
    this.setState({ isLoading: true });

    fetch(API + DEFAULT_QUERY)
      .then(response => {
        if (response.ok) {
          return response.json();
        } else {
          throw new Error('Something went wrong ...');
        }
      })
      .then(data => this.setState({ hits: data.hits, isLoading: false }))
      .catch(error => this.setState({ error, isLoading: false }));
  }

  ...

}
复制代码
  • 当然,我们完全可以展示错误提示。
代码语言:javascript
代码运行次数:0
运行
复制
...

class App extends Component {

  ...

  render() {
    const { hits, isLoading, error } = this.state;

    if (error) {
      return <p>{error.message}p>;
    }

    if (isLoading) {
      return <p>Loading ...p>;
    }

    return (
      <ul>
        {hits.map(hit =>
          <li key={hit.objectID}>
            <a href={hit.url}>{hit.title}a>
          li>
        )}
      ul>
    );
  }
}
复制代码

使用 Axios 来获取数据

代码语言:javascript
代码运行次数:0
运行
复制
import React, { Component } from 'react';
import axios from 'axios';

const API = 'https://hn.algolia.com/api/v1/search?query=';
const DEFAULT_QUERY = 'redux';

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      hits: [],
      isLoading: false,
      error: null,
    };
  }

  componentDidMount() {
    this.setState({ isLoading: true });

    axios.get(API + DEFAULT_QUERY)
      .then(result => this.setState({
        hits: result.data.hits,
        isLoading: false
      }))
      .catch(error => this.setState({
        error,
        isLoading: false
      }));
  }

  ...
}

export default App;
复制代码

使用 Async/Await 来获取数据

代码语言:javascript
代码运行次数:0
运行
复制
import React, { Component } from 'react';
import axios from 'axios';

const API = 'https://hn.algolia.com/api/v1/search?query=';
const DEFAULT_QUERY = 'redux';

class App extends Component {
  ...

  async componentDidMount() {
    this.setState({ isLoading: true });

    try {
      const result = await axios.get(API + DEFAULT_QUERY);

      this.setState({
        hits: result.data.hits,
        isLoading: false
      });
    } catch (error) {
      this.setState({
        error,
        isLoading: false
      });
    }
  }

  ...
}

export default App;
复制代码

使用 高阶组件来获取数据

代码语言:javascript
代码运行次数:0
运行
复制
const withFetching = (url) => (Component) =>
  class WithFetching extends React.Component {
    constructor(props) {
      super(props);

      this.state = {
        data: null,
        isLoading: false,
        error: null,
      };
    }

    componentDidMount() {
      this.setState({ isLoading: true });

      axios.get(url)
        .then(result => this.setState({
          data: result.data,
          isLoading: false
        }))
        .catch(error => this.setState({
          error,
          isLoading: false
        }));
    }

    render() {
      return <Component { ...this.props } { ...this.state } />;
    }
  }
复制代码
  • 怎么使用
代码语言:javascript
代码运行次数:0
运行
复制
const withFetching = (url, query) => (Comp) =>
  ...
复制代码

参考

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 怎么优雅的使用 react 获取数据
    • 使用 JavaScript Promises 去处理数据
    • 怎么优雅的处理 loading 和 error?
      • loading 加载中处理
      • Error 处理
    • 使用 Axios 来获取数据
    • 使用 Async/Await 来获取数据
    • 使用 高阶组件来获取数据
  • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档