【问题标题】:Fetch graphql query result on render and re-renders BUT LAZILY在渲染和重新渲染时获取 graphql 查询结果但懒惰
【发布时间】:2020-05-02 09:49:04
【问题描述】:

我有一个 React Apollo 应用程序,我想要做的是我有一个使用图表呈现一些数据的组件。对于这些数据,我有一些过滤器保存在组件的本地状态中(使用钩子)

const [filters, setFilters] = useState(defaultFilters);

现在我想要的是,每当安装组件时,使用默认过滤器获取数据。但我也想在用户更新过滤器时重新获取数据并点击提交,我会使用新的过滤器获取结果。

由于我还想获取过滤器更新的结果,所以我使用的是 apollo 提供的 useLazyQuery 钩子

const [getData, {data}] = useLazyQuery(GET_DATA_QUERY, { variables: {filters} });

useEffect(getData, []); // this useEffect runs only when the component mounts and never again

但是,每当我的状态 filters 更新时,getData 函数就会自动运行!总是! (幕后)

  1. 如何处理这种情况,我想获取挂载和重新渲染的结果。 我曾尝试使用 useQuery 并重新获取它提供的,但我在那里遇到了同样的问题,每当我更新状态时,组件都会重新呈现,并且 useQuery 挂钩会运行并进行调用。 (这就是我相信它的运行方式)

  2. 如何修复我当前的代码。在 useEffect 函数中调用 getData 函数使其在每次重新渲染时运行。

我认为我在这个stackoverflow-question 中定义的问题与我的有些相似。

【问题讨论】:

    标签: javascript reactjs graphql react-apollo apollo-client


    【解决方案1】:

    部分问题在于您确实有两种不同的状态,您正试图利用一个钩子来实现。您有表示 UI 中输入值的状态,然后您有表示要实际应用于图表的过滤器的状态。这是两个独立的状态位。

    最简单的解决方案就是这样做:

    const [inputFilters, setInputFilters] = useState(defaultFilters)
    const [appliedFilters, setAppliedFilters] = useState(inputFilters)
    const { data } = useQuery(GET_DATA_QUERY, { variables: { filters: appliedFilters } })
    
    const handleSubmit = () => setAppliedFilters(inputFilters)
    const handleSomeInputChange = event => setInputFilters(...)
    

    这样,您只使用inputFilters/setInputFilters 来管理您的输入状态。当用户单击您的提交按钮时,appliedFilters 将设置为当时的 inputFilters,您的查询将更新以反映新变量。

    【讨论】:

    • 好的,所以基本上,当我更新 inputFilters 时,组件会重新渲染,并且 useQuery 挂钩未运行,因为其中未使用 inputFilters 状态。是这样吗?
    • 好的,谢谢。还有一个问题,究竟是什么在控制这部分?就像我在这个功能组件中创建一个函数并像const [inputFilters, setInputFilters] = useState(defaultFilters) const [appliedFilters, setAppliedFilters] = useState(inputFilters) const { data } = useQuery(GET_DATA_QUERY, { variables: { filters: appliedFilters } }) const tempFun = (appliedFilters) => { console.log("TEMP FUN RUN"); } 那样传递给它应用的过滤器,这个 tempFun 总是运行但 useQuery 钩子不运行。那么它是 useQuery 管理在应用过滤器更新上运行查询吗?
    • 另外,这种方法似乎有1个问题,如果用户再次点击提交,只是为了刷新数据,不更改过滤器,查询将不会获取新结果! :\
    • useQuery 总是在渲染时被调用,但在内部它不会发出另一个请求,除非选项发生变化或者你已经将 fetchPolicy 设置为,例如,network-only。跨度>
    • 如果您想在每次点击提交时发送请求,您可以将inputFiltersappliedFilters 进行比较,如果它们相等,则不要调用setAppliedFilters,而是调用refetchrefetchuseQuery 挂钩返回,可以调用以手动触发重新获取查询。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-14
    • 2016-12-30
    • 1970-01-01
    • 2020-06-13
    • 2019-06-01
    • 1970-01-01
    相关资源
    最近更新 更多