【发布时间】:2021-08-13 13:41:40
【问题描述】:
对于一个 React 项目,我使用多个上下文提供程序运行 GraphQL 查询,为所有或部分组件提供我需要的数据。对于这个例子,我有一个 BookProvider 可以查询特定用户的所有书籍。
export const BookProvider = ({ children }) => {
// GraphQL query for retrieving the user-belonged books
const { loading, data } = useQuery(gql`{
books {
id,
name,
description
}
}
`, {
pollInterval: 500
})
if(!data?.books) return null
return (
<BookContext.Provider value={data?.books}>
{!loading && children}
</BookContext.Provider>
)
}
我确保查询未加载并且在 data 对象中可用。为了检索我的数据,我在此提供程序中包装了一个仪表板组件。在这里,还有其他组件加载相应的数据。
const Dashboard = () => {
return (
<BookProvider>
// More components for loading data
</BookProvider>
)
}
数据是这样加载的:
const { id, name } = useContext(BookContext)
以同样的方式,我有一个AuthenticationProvider,包装了整个应用程序。
export const MeQuery = gql`{ me { id, email } }`
export const AuthenticationProvider = (props) => {
const { loading, data } = useQuery(MeQuery)
if(loading) return null
const value = {
user: (data && data.me) || null
}
return <AuthenticationContext.Provider value={value} {...props} />
}
对于我的应用程序路由,检查用户是否经过身份验证,我使用PrivateRoute 组件。 Dashboard 组件由此 PrivateRoute 加载。
const PrivateRoute = ({ component: Component, ...rest }) => {
const { user } = useAuthentication()
return user ? <Route {...rest} render={props => <Component {...props} />} /> : <Redirect to={{ pathname: '/login' }} />
}
登录时,设置用户对象,没有问题,但是,注销时,这是Dashboard上的一个组件,它将我重定向到登录页面,但我收到以下错误:
index.js:1 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.
at BookProvider (http://localhost:3000/static/js/main.chunk.js:2869:3)
at Dashboard
at Route (http://localhost:3000/static/js/vendors~main.chunk.js:85417:29)
at PrivateRoute (http://localhost:3000/static/js/main.chunk.js:4180:14)
at Switch (http://localhost:3000/static/js/vendors~main.chunk.js:85619:29)
at Router (http://localhost:3000/static/js/vendors~main.chunk.js:85052:30)
at BrowserRouter (http://localhost:3000/static/js/vendors~main.chunk.js:84672:35)
at Router
对于注销,我使用以下代码:
export function useLogout() {
const client = useApolloClient()
const logout = useMutation(gql`mutation Logout { logout }`, { update: async cache => {
cache.writeQuery({ query: MeQuery, data: { me: null }})
await client.resetStore()
}})
return logout
}
export default useLogout
这被称为const [logout] = useLogout()
问题
- 为什么会出现这个错误?
- 如何解决这个问题?
- 在上下文提供程序中运行查询是一种好习惯吗?
【问题讨论】:
标签: reactjs graphql react-apollo react-context