在发出API请求时,在React中将父组件的函数错误传播到子组件

时间:2018-01-04 10:39:56

标签: javascript reactjs redux react-redux fetch

我有一个公共post request function,我在这里获取数据并将数据返回给调用函数。并且此函数作为prop传递给其他组件。

现在如果我在获取数据时遇到错误,我想将相同的错误发送到最终component redux,以便我可以相应地显示该组件中的错误。

export const post = async (url, payload) => {
  const data = await fetch(url, {
    method: 'POST',
    body: JSON.stringify(payload),
    headers
  })
    .then(res => {
      return res.json()
    })
    .catch(err => {
      throw err
    })
  return data
}

此处ParentFunction存在于父组件中,并且它作为prop传递给子组件。

function ParentFunction(url, payload) {
  postRequest(url, payload).then()
    .catch()
}

并将此函数引用传递为:

<ChildComponent fetch={this.fun1} />

这是我的子组件redux中的函数,当前我正在获取数据,只要我没有从post post获取错误

function fun2() {
  this.props.fetch.then(data => dispatch(....))
  // doing something with this data 
}

现在如果我从post请求中收到错误,我会将相同内容从父级传递给此函数,但是此fun2会抛出错误,指出fun1.then不是函数。那么我怎么能在这里捕捉错误呢。 我尝试使用fun1.then().catch(),但它无效。

有什么方法可以实现这个目的吗?

TL; DR:

如何在Promise中包装fetch调用,以便在抛出错误时可以使用.catch?

1 个答案:

答案 0 :(得分:1)

让我向你解释你所得到的错误。

您正在使用async / await返回结果(而非承诺),当有异常时,它会抛出。

由于它不是承诺,因此它不会为您提供.then.catch

实现您尝试做的事情的一种方法是,调用该函数,在try/catch块之间包裹调用,然后您就可以了。您将通过函数调用获取数据,或者您将在catch块中获取错误。基于此,您可以处理如何将它们传递给道具。

示例示例:

export const post = async (url, payload) => {
  const data = await fetch(url, {
    method: 'POST',
    body: JSON.stringify(payload),
    headers
  })
    .then(res => {
      return res.json()
    })
    .catch(err => {
      throw err
    })
  return data
}

现在在调用它时:

let data = null;
let error = null;
try {
  data = post(url, payload)
} catch (e) {
  error = e;
}

另一种方法是返回数组作为结果。基本结构可以是[err, data]。如果您成功获取数据,请返回[null, data]。如果您收到例外,请返回[err]

示例示例:

export const post = async (url, payload) => {
  const data = await fetch(url, {
    method: 'POST',
    body: JSON.stringify(payload),
    headers
  })
    .then(res => {
      return [null, res.json()]
    })
    .catch(err => {
      return [err]
    })

  return data
}

或者,您只需使用承诺就可以使用您正在尝试的常用.then.catch

以下是此示例:

export const post = (url, payload) => {
      return fetch(url, {
        method: 'POST',
        body: JSON.stringify(payload),
        headers
      })
        .then(res => {
          return res.json()
        }) // as you will be catching the exception later, we can exclude catch from here...
    }

以下是您的称呼方式:

post(url, payload)
  .then((data) => {
    // handle data
  })
  .catch((err) => {
    // handle error
  })

我希望这会有所帮助。