【问题标题】:componentDidCatch is not triggered even when I throw an error in my constructor即使我在构造函数中抛出错误,也不会触发 componentDidCatch
【发布时间】:2018-05-09 10:31:13
【问题描述】:

我似乎无法在我的代码中触发 componentDidCatch,即使我故意在我的构造函数中抛出错误,所以我知道我没有在事件处理程序上抛出错误。我担心的是我没有成功地将我的项目更新到 React 16,这就是 componentDidCatch 不起作用的原因。可能是我没有成功升级到 React 16,还是我滥用了错误边界?

以下是我已经查看并使用过的帖子:

  1. Error handling in React best practices

  2. React 16 Error Boundary component (using componentDidCatch) shows uncaught error

  3. Introducing Error Boundaries

App.js

import React, { Component } from 'react'
import axios from 'axios'

import ErrorBoundary from './components/ErrorBoundary'
import Home from './components/Home'
import Login from './components/Login'

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

    this.state = {
      loggedIn: false,
      hasError: false
    }
    // This is where I am throwing my Error
    throw new Error('this should be caught')
  }

  componentWillMount () {
    axios.get(this.url, {
      withCredentials: true
    })
    .then((response) => {
      if (response.status === 200) { 
        if (response.data.isAuthenticated) {
          this.setState({ loggedIn: true })
        } else if (!response.data.isAuthenticated) {
          this.setState({ loggedIn: false })
        } 
      }
    })
    .catch((error) => {
      this.setState(state => ({ ...state, hasErrors: true }))
      throw new Error("We couldn't get a response from the server.")
    })
  }

  render () {
    if (!this.state.loggedIn && !this.state.hasErrors) {
      return (
        <div className='login-container'>
          // I am setting an Error Boundary
          <ErrorBoundary>
            <Login url={this.url} />
          </ErrorBoundary>
        </div>
      )
    } else if (this.state.loggedIn && !this.state.hasErrors) {
      return (
        <div>
          // I am setting an Error Boundary
          <ErrorBoundary>
            <Home url={this.url} />
          </ErrorBoundary>
        </div>
      )
    } else { 
      return <h1>Something has gone wrong.</h1>
    }
  }
}

export default App

ErrorBoundary.js

import React, { Component } from 'react'

class ErrorBoundary extends Component {
  constructor (props) {
    super(props)
    this.state = { hasError: false }
  }

  componentDidCatch (error, info) {
    this.setState(state => ({ ...state, hasError: true }))
  }

  render () {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>
    }
    return this.props.children
  }
}

export default ErrorBoundary

package.json

{
  "name": "spotify-analyzer-frontend",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "babel-eslint": "^7.2.3",
    "dotenv": "^4.0.0",
    "flexbox-react": "^4.4.0",
    "highcharts": "^5.0.14",
    "material-ui-search-bar": "^0.4.0",
    "prop-types": "^15.6.0",
    "react": "^16.1.1",
    "react-dom": "^16.1.1",
    "react-flexbox-grid": "^2.0.0",
    "react-highcharts": "^12.0.0",
    "react-jss": "^8.0.0",
    "react-scripts": "1.0.11",
    "react-tap-event-plugin": "^2.0.1",
    "standard": "^10.0.3"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "proxy": "https://spotify-viz-api.herokuapp.com",
  "devDependencies": {
    "axios": "^0.16.2",
    "babel-eslint": "^8.0.2",
    "babel-jest": "^21.0.0",
    "css.escape": "^1.5.1",
    "enzyme": "^3.2.0",
    "enzyme-adapter-react-16": "^1.1.0",
    "eslint": "^4.5.0",
    "eslint-plugin-react": "^7.3.0",
    "jest": "^21.0.1",
    "material-ui": "^0.19.1",
    "regenerator-runtime": "^0.11.0",
    "standard": "^10.0.3"
  },
  "standard": {
    "ignore": [
      "__tests__/**.test.js"
    ]
  }
}

node_modules/react/package.json

    {
  "_args": [
    [
      {
        "raw": "react@next",
        "scope": null,
        "escapedName": "react",
        "name": "react",
        "rawSpec": "next",
        "spec": "next",
        "type": "tag"
      },
      "/Users/maecapozzi/Desktop/Codes/spotify-analyzer-frontend"
    ]
  ],
  "_from": "react@next",
  "_id": "react@16.1.1",
  "_inCache": true,
  "_location": "/react",
  "_nodeVersion": "8.6.0",
  "_npmOperationalInternal": {
    "host": "s3://npm-registry-packages",
    "tmp": "tmp/react-16.1.1.tgz_1510589592482_0.18714527692645788"
  },
  "_npmUser": {
    "name": "gaearon",
    "email": "dan.abramov@gmail.com"
  },
  "_npmVersion": "5.5.1",
  "_phantomChildren": {},
  "_requested": {
    "raw": "react@next",
    "scope": null,
    "escapedName": "react",
    "name": "react",
    "rawSpec": "next",
    "spec": "next",
    "type": "tag"
  },
  "_requiredBy": [
    "#USER",
    "/"
  ],
  "_resolved": "https://registry.npmjs.org/react/-/react-16.1.1.tgz",
  "_shasum": "d5c4ef795507e3012282dd51261ff9c0e824fe1f",
  "_shrinkwrap": null,
  "_spec": "react@next",
  "_where": "/Users/maecapozzi/Desktop/Codes/spotify-analyzer-frontend",
  "browserify": {
    "transform": [
      "loose-envify"
    ]
  },
  "bugs": {
    "url": "https://github.com/facebook/react/issues"
  },
  "dependencies": {
    "fbjs": "^0.8.16",
    "loose-envify": "^1.1.0",
    "object-assign": "^4.1.1",
    "prop-types": "^15.6.0"
  },
  "description": "React is a JavaScript library for building user interfaces.",
  "devDependencies": {},
  "directories": {},
  "dist": {
    "integrity": "sha512-FQfiFfk2z2Fk87OngNJHT05KyC9DOVn8LPeB7ZX+9u5+yU1JK6o5ozRlU3PeOMr0IFkWNvgn9jU8/IhRxR1F0g==",
    "shasum": "d5c4ef795507e3012282dd51261ff9c0e824fe1f",
    "tarball": "https://registry.npmjs.org/react/-/react-16.1.1.tgz"
  },
  "engines": {
    "node": ">=0.10.0"
  },
  "files": [
    "LICENSE",
    "README.md",
    "index.js",
    "cjs/",
    "umd/"
  ],
  "homepage": "https://reactjs.org/",
  "keywords": [
    "react"
  ],
  "license": "MIT",
  "main": "index.js",
  "maintainers": [
    {
      "name": "acdlite",
      "email": "acdlite@me.com"
    },
    {
      "name": "sophiebits",
      "email": "npm@sophiebits.com"
    },
    {
      "name": "flarnie",
      "email": "flarnie.npm@gmail.com"
    },
    {
      "name": "gaearon",
      "email": "dan.abramov@gmail.com"
    },
    {
      "name": "trueadm",
      "email": "dg@domgan.com"
    },
    {
      "name": "brianvaughn",
      "email": "briandavidvaughn@gmail.com"
    },
    {
      "name": "fb",
      "email": "opensource+npm@fb.com"
    }
  ],
  "name": "react",
  "optionalDependencies": {},
  "readme": "ERROR: No README data found!",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/facebook/react.git"
  },
  "version": "16.1.1"
}

【问题讨论】:

  • 确认你安装的 React 版本是个好主意。检查项目中的package-lock.json 文件并搜索“react”。或者直接查看node_modules/react文件夹,查看react的package.json
  • 嗨@Sidney,如果你不介意看一下,我已经添加了我的node_modules/react/package.json 文件。它似乎说我有 react@16.1.1。
  • 您可以通过从render返回一个简单字符串来测试您是否已成功升级到16.x,直到16 gist.github.com/ahmedtehseen/…才支持该字符串

标签: javascript reactjs error-handling ecmascript-6


【解决方案1】:

因此,从您的代码看来,您正在向父级抛出错误。

错误边界是 React 组件,可在其子组件树中的任何位置捕获 JavaScript 错误,记录这些错误并显示回退 UI

错误边界在其组件树中捕获错误。

因此,您的&lt;Home&gt;&lt;Login&gt; 组件中需要有错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-06
    • 1970-01-01
    • 2020-09-04
    • 1970-01-01
    • 2018-07-18
    相关资源
    最近更新 更多