如何在 react 的基本应用程序组件中使用 GraphQL 钩子而无需重新渲染?



我正在尝试在 React 上使用带有 GraphQLconst sliceQuery = useQuery(ALL_SLICES)的 redux,但由于 GraphQL 钩子及其承诺Object { data: {}, variables: {}, refetch: (), fetchMore: (), updateQuery: (), startPolling: (), stopPolling: (), subscribeToMore: (), loading: true, networkStatus: 1, … },我似乎无法使用 useEffect 来最小化渲染。因此,我被迫在 useEffect 之外更新props.slices,因为我必须等待 GraphQL 钩子完成加载

,如下所示:
if (!sliceQuery.loading && props.slices === null) {
const allSlices = sliceQuery.data.allSlices
props.initializeSlices(allSlices)
props.setCurrentSlice(allSlices.find(s => s._id === splitUrl[5]))
}

这是我完整的App.js组件:

import React, { useEffect } from 'react'
import { initializeSlices } from './reducers/sliceReducer'
import { setCurrentSlice } from './reducers/currentSliceReducer'
import { connect } from 'react-redux'
import { BrowserRouter as Router, Route } from 'react-router-dom'
import { useQuery } from '@apollo/react-hooks'
import NavBar from './components/navBar/NavBar'
import Slice from './components/pages/Slice'
import About from './components/pages/About'
import Policies from './components/pages/Policies'
import Contact from './components/pages/Contact'
import './static/css/base.css'
import { ALL_SLICES } from './schemas'
const App = (props) => {
console.log('App.js is ran')
const sliceQuery = useQuery(ALL_SLICES)
const splitUrl = window.location.href.split('/')
if (!sliceQuery.loading && props.slices === null) {
const allSlices = sliceQuery.data.allSlices
props.initializeSlices(allSlices)
props.setCurrentSlice(allSlices.find(s => s._id === splitUrl[5]))
}
const getSliceById = (id) => {
return props.slices.find(s => s._id === id)
}
if (!props.slices || !props.currentSlice) {
return (
<div>
<h1>loading..</h1>
</div>
)
}
return (
<div className="wrapper">
<Router>
<NavBar />
<Route exact path="/" render={() => <Slice slice={getSliceById('5e2db26efa3d070ec879b0e9')} /> } />
<Route path="/slice/:name/:id" render={({match}) => <Slice slice={getSliceById(match.params.id)} /> } />
<Route path="/about" render={() => <About /> } />
<Route path="/policies" render={() => <Policies /> } />
<Route path="/contact" render={() => <Contact /> } />
</Router>
</div>
);
}
const mapStateToProps = (state) => {
return {
slices: state.slices,
currentSlice: state.currentSlice,
}
}
export default connect(
mapStateToProps,
{ initializeSlices, setCurrentSlice }
)(App)

以下是页面加载的控制台日志:

开发服务器已断开连接。 如有必要,请刷新页面。

[HMR] 正在等待来自 WDS 的更新信号...

应用.js正在运行

./src/App.js 第 1:17 行:"useEffect"已定义,但从未使用 no-un-used-va

警告:渲染方法应该是 props 和状态的纯函数;不允许从渲染触发嵌套组件更新。如有必要,请在组件 DidUpdate 中触发嵌套更新。 检查应用程序的渲染方法。

应用.js正在运行

应用.js正在运行

应用.js正在运行

您仍然可以使用useEffect仅在数据可用时执行方法。

const allSlices = 
!sliceQuery.loading && props.slices === null 
? sliceQuery.data.allSlices 
: null;
useEffect(() => {
if(allSlices !== null) {
props.initializeSlices(allSlices)
props.setCurrentSlice(allSlices.find(s => s._id === splitUrl[5]))
}
}, [allSlices, props.initializeSlices, props.setCurrentSlice])

这只会调用方法props.initializeSlices,并在allSlices可用时props.setCurrentSlice

如果这些方法也是在渲染时创建的,则可能需要使用创建它们useCallback来阻止它们触发要在后续渲染上执行的useEffect挂钩。

相关内容

  • 没有找到相关文章

最新更新