状态变化时如何防止 useQuery 运行?
Posted
技术标签:
【中文标题】状态变化时如何防止 useQuery 运行?【英文标题】:How to prevent useQuery for running when state changes? 【发布时间】:2020-07-03 02:03:52 【问题描述】:我正在使用 React Apollo 从我的服务器获取数据。当我的页面加载时,我使用 useQuery 来检索数据。这工作正常。问题是当我对搜索表单进行更改时,这会更新导致不需要的重新渲染并再次调用服务器的状态。
我只想在页面加载和单击搜索按钮时调用服务器。
使用查询:
const loading: loadingLessons, error: lessonsError, data: lessons = useQuery(
LESSON_BY_PARAMS,
variables: findLessonsInput: searchParams ,
,
);
当我更改表单字段时,它会调用 updateFormField 来更新导致重新渲染的 redux 状态
<Autocomplete
options=categories
getOptionLabel=(option: any) => option.label
inputValue=form.category
defaultValue=() =>
const value = categories.find(option => option.label === form.category);
return value;
onChange=(event, value) => updateFormField('category', value?.label)
renderInput=params => (
<TextField ...params label="Category" variant="outlined" fullWidth />
)
/>
我正在使用反应钩子。
【问题讨论】:
【参考方案1】:查看skip 选项,该选项可用于完全跳过查询。你可以这样做:
const [skip, setSkip] = React.useState(false)
const loading, data = useQuery(QUERY, skip )
React.useEffect(() =>
// check whether data exists
if (!loading && !!data)
setSkip(true)
, [data, loading])
因此,一旦数据返回,您只需将跳过选项设置为 true。如果你想发出请求,你应该在搜索按钮上处理 onClick(只需 setSkip(false))。
【讨论】:
【参考方案2】:如果您使用纯 apollo 客户端,您将失去 apollo 的一些功能。无需将 graphql 调用移动到 redux 操作中,您可以在 Redux 中使用选择器来防止组件重新加载或对服务器进行不必要的调用。
Selectors in Redux
【讨论】:
【参考方案3】:感谢@Vadim Sheremetov 的建议,但我决定将 api 调用移至 redux-thunk 函数:
当页面加载时,我发送一个动作,传递它搜索参数和 apollo 客户端:
const client = useApolloClient();
useEffect(() =>
loadLessons(searchParams, client);
, [location.search]);
const mapDispatchToProps = dispatch =>
return
loadLessons: (searchParams, client) =>
dispatch(loadLessonsAction(searchParams, client)),
;
;
该操作调用一个 redux thunk 函数,然后调度另一个更新状态的操作:
actions.ts:
export function loadLessonsAction(searchParams: any, client: ApolloClient<object>):
any
return async function(dispatch)
try
const data = await client.query(
query: LESSON_BY_PARAMS,
variables: findLessonsInput: searchParams ,
);
dispatch(loadLessonsSuccessAction(data.lessonsByParams));
catch (error)
;
export function loadLessonsSuccessAction(lessons: any[]): FilterPanelActionTypes
return
type: LOAD_LESSONS_SUCCESS,
payload: lessons,
;
reducer.ts:
case LOAD_LESSONS_SUCCESS:
return
...state,
lessons: action.payload.lessons,
lessonCount: action.payload.count,
;
【讨论】:
以上是关于状态变化时如何防止 useQuery 运行?的主要内容,如果未能解决你的问题,请参考以下文章
如何防止 Apollo 客户端 useQuery 中的错误传播?