我正在使用React Apollo从服务器获取数据。加载页面时,我正在使用useQuery来检索数据。这很好。问题是当我更改搜索表单时,这会更新状态,从而导致不必要的重新渲染,从而再次调用服务器。
我只想在页面加载时以及单击搜索按钮时才调用服务器。
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 />
)}
/>
我正在使用反应钩子。
答案 0 :(得分:4)
看看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])
因此,一旦返回数据,您只需将skip选项设置为true。如果要发出请求,则应处理搜索按钮上的onClick(只需setSkip(false))。
答案 1 :(得分:0)
感谢@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,
};
}
答案 2 :(得分:0)
如果您使用纯apollo客户端,则将失去apollo的某些功能。无需将graphql调用移入redux动作,您可以在Redux中使用选择器来防止组件重新加载或对服务器进行不必要的调用。