React 说我正在对未安装的组件执行状态更新,但我的组件(似乎已安装)? [复制]

Posted

技术标签:

【中文标题】React 说我正在对未安装的组件执行状态更新,但我的组件(似乎已安装)? [复制]【英文标题】:React says I'm performing a state update on an unmounted component, but my component (appears to be) mounted? [duplicate] 【发布时间】:2020-08-30 07:57:27 【问题描述】:

请原谅我,因为我知道我是导致此错误的人,但我不知道如何 - 我是 React 新手。

我有一个已安装的组件。该组件从 GitHub 获取流行存储库的列表。该组件有效地允许您过滤按语言返回的存储库列表。该组件使用 componentDidMount() 生命周期方法来触发对 GitHub API 的请求。在那之后,单击不同的 Nav 元素会触发对 GitHub API 的请求。返回的 repos 列表缓存在 state 中。

请注意,该错误仅在页面加载和刷新时发生,这一点似乎很重要。向 3rd 方 API 发送新请求以获取新的 repos 列表不会产生错误。更令我困惑的是,该应用程序显然运行良好 - 在页面加载时,我得到了正确呈现的存储库列表(显示在某些卡片组件中)。

组件本身是:

export default class Popular extends React.Component 
  state = 
    selectedLanguage: 'All',
    repos: ,
    error: null
  

  componentDidMount() 
    this.updateLanguage(this.state.selectedLanguage)
  

  updateLanguage = (selectedLanguage) => 
    this.setState(
      selectedLanguage,
      error: null
    )

    if (!this.state.repos[selectedLanguage]) 
      fetchPopularRepos(selectedLanguage)
        .then(data => 
          this.setState(( repos ) => (
            repos: 
              ...repos,
              [selectedLanguage]: data,
            
          ))
        )
        .catch(() => 
          console.warn('Error fetching repos: ')

          this.setState(
            error: 'There was an error fetching the repositories.'
          )
        )
    
  

  isLoading = () => 
    const  selectedLanguage, repos, error  = this.state;

    return !repos[selectedLanguage] && error === null
  

  render() 
    const  selectedLanguage, repos, error  = this.state

    return (
      <React.Fragment>
        <LanguagesNav
          selected=selectedLanguage
          onUpdateLanguage=this.updateLanguage
        />

        this.isLoading() && <Loading text='Fetching Repos' />

        error && <p className='center-text error'>error</p>

        repos[selectedLanguage] && <ReposGrid repos=repos[selectedLanguage] />
      </React.Fragment>
    )
  


在浏览器中,我收到“无法在未安装的组件上执行状态更新”,并且 React 开发工具表明错误来自 setState 调用返回的承诺中的 fetchPopularRepos

第三方API的获取如下图所示:

export function fetchPopularRepos(language) 
  const endpoint = window.encodeURI(`https://api.github.com/search/repositories?q=stars:>1+language:$language&sort=stars&order=desc&type=Repositories `);

  return fetch(endpoint)
    .then(res => res.json())
    .then(data => 
      if (!data.items) 
        throw new Error(data.message)
      

      return data.items
    )

还有我的 index.js 正在渲染 App 组件:

class App extends React.Component 
  state = 
    theme: 'light',
    toggleTheme: () => 
      this.setState(( theme ) => (
        theme: theme === 'light' ? 'dark' : 'light'
      ))
    
  

  render() 
    return (
      <Router>
        <ThemeProvider value=this.state>
          <div className=this.state.theme>
            <div className='container'>
              <Nav />

              <Switch>
                <Route exact path='/' component=Popular />
                <Route exact path='/battle' component=Battle />
                <Route path='/battle/results' component=Results />
                <Route component=NotFound />
              </Switch>
            </div>
          </div>
        </ThemeProvider>
      </Router>
    )
  

编辑:添加了堆栈跟踪的屏幕截图。 编辑 2:添加 Router/index.js 文件

【问题讨论】:

它可能很快被卸载并再次安装! 你能出示一下你的路由器吗? 是的,将编辑它。 【参考方案1】:

我以前做过你做的事情,这是因为ThemeProvider

您在Router 中设置ThemeProvider 的主题。

尝试在其他组件的Router 之外定义ThemeProvider

App.js:

class App extends React.Component 
  state = 
    theme: 'light',
    toggleTheme: () => 
      this.setState(( theme ) => (
        theme: theme === 'light' ? 'dark' : 'light'
      ))
    
  

  render() 
    return (
        <ThemeProvider value=this.state>
          <div className=this.state.theme>
            <Routes />
          </div>
        </ThemeProvider>
    )
  

Routes.js:

class Routes extends React.Component 
  render() 
    return (
      <Router>
        <div className="container">
          <Nav />
          <Switch>
            <Route exact path="/" component=Popular />
            <Route exact path="/battle" component=Battle />
            <Route path="/battle/results" component=Results />
            <Route component=NotFound />
          </Switch>
        </div>
      </Router>
    )
  

【讨论】:

很遗憾,这并不能解决问题。

以上是关于React 说我正在对未安装的组件执行状态更新,但我的组件(似乎已安装)? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

警告:无法在 React 本机中对未安装的组件执行 React 状态更新

反应钩子。无法对未安装的组件执行 React 状态更新

无法对未安装的组件执行 React 状态更新。内存泄漏

警告:无法对未安装的组件执行 React 状态更新

无法对未安装的组件执行 React 状态更新(useEffect 反应挂钩)

“警告:无法对未安装的组件执行 React 状态更新。” [关闭]