首页 > 解决方案 > React-Apollo - 查询 - renderProp:反应警告:无法对未安装的组件执行反应状态更新

问题描述

我正在使用“react-apollo”中的“Query”,我的应用程序返回了这个错误。我想我理解了这个问题:我的应用程序正在尝试重新渲染一个已卸载的组件。我不确定如何解决该错误。我一直在阅读 Apollo 和 React 的官方文档,但我仍然不知道如何修复。

似乎其他用户和我有同样的问题:https ://github.com/apollographql/react-apollo/issues/3635

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
    in Query (at GetListOfUsers.js:19)
    in GetListOfUsers (at UserAdministration.js:11)
    in UserAdministration (at App.js:54)

这是我的代码:

// GetListOfUsers.js

import React from 'react'

import { ListOfUsers } from '../components/ListOfUsers'
import { Spinner } from '../components/Spinner'
import { ErrorAlert } from '../components/ErrorAlert'

import { Query } from 'react-apollo'

import { LIST_ALL_USERS } from '../gql/queries/users';

const renderProp = ( { loading, error, data } ) => {
    if (loading) return <Spinner key={'loading'} />
    if (error) return <ErrorAlert errorMessage={error.message} />

    return <ListOfUsers users={data.listAllUsers || []} />
}

export const GetListOfUsers = () => (
    <Query query={LIST_ALL_USERS} fetchPolicy="cache-and-network">
        {
            renderProp
        }
    </Query>
)

// ListOfUsers.js

import React from 'react'
import PropTypes from 'prop-types'

import { parseUnixTimestamp } from '../../utils/utils'

export const ListOfUsers = ( { users = [] } ) => {
    return (
        <section className="table-responsive">
            <table className="table text-light">
                <thead>
                    <tr>
                        <th scope="col">Email</th>
                        <th scope="col">Is administrator ?</th>
                        <th scope="col">Is active ?</th>
                        <th scope="col">Registration date</th>
                        <th scope="col">Last login</th>
                    </tr>
                </thead>
                <tbody>
                    {
                        users.map(user => {
                            return (
                                <tr key={user.uuid}>
                                    <td>{user.email}</td>
                                    <td>{(user.isAdmin) ? 'yes': 'no'}</td>
                                    <td>{(user.isActive) ? 'yes': 'no'}</td>
                                    <td>{parseUnixTimestamp(user.registrationDate)}</td>
                                    <td>{parseUnixTimestamp(user.lastLogin)}</td>
                                </tr>
                            )
                        })
                    }
                </tbody>
            </table>
        </section>
    )
}


ListOfUsers.propTypes = {
    users: PropTypes.arrayOf(
        PropTypes.shape({
            email: PropTypes.string.isRequired,
            uuid: PropTypes.string.isRequired,
            isAdmin: PropTypes.bool.isRequired,
            isActive: PropTypes.bool.isRequired,
            registrationDate: PropTypes.string.isRequired,
            lastLogin: PropTypes.string.isRequired
        })
    )
}

“GetListOfUsers”在这里被调用:

// UserAdministration.js

import React, { Fragment } from 'react'

import { PageTitle } from '../components/PageTitle'

import { GetListOfUsers } from '../containers/GetListOfUsers'

const UserAdministration = () => {
    return (
        <Fragment>
            <PageTitle text='User administration panel' />
            <GetListOfUsers />
        </Fragment>
    )
}

UserAdministration.displayName = 'UserAdministration'

export default UserAdministration

我试图修改文件“GetListOfUsers”以使用“useQuery”并且遇到了同样的问题。我的代码是这样的:

// GetListOfUsers.js

import React from 'react'
import { useQuery } from 'react-apollo'

import { Spinner } from '../components/Spinner'
import { ErrorAlert } from '../components/ErrorAlert'
import { ListOfUsers } from '../components/ListOfUsers'

import { LIST_ALL_USERS } from '../gql/queries/users';

export const GetListOfUsers = () => {
    const { loading, error, data } = useQuery(LIST_ALL_USERS);

    if (loading) return <Spinner />
    if (error) return <ErrorAlert errorMessage={error.message} />

    return <ListOfUsers users={data.listAllUsers || []} />
}

标签: reactjsreact-apolloapollo-client

解决方案


我遇到了同样的问题,并为我的案例找到了两种解决方案:

  1. 删除fetchPolicy: 'cache-and-network'(也许不是你想要的)

或者

  1. 将 Apollo 升级到新的 v3.0(撰写此答案时仍处于测试阶段)

这两个选项都修复了对我的警告。


推荐阅读