如何使用useQuery挂钩在其他挂钩中填充状态?

时间:2019-04-02 10:09:05

标签: reactjs react-apollo react-hooks

最近我一直在处理与挂钩相关的一些问题,因为我一直在我的项目中实现挂钩。我不断收到错误消息:“渲染的钩子比上一个渲染期间要多。”

看来,让我的代码正常工作的唯一方法是将useQuery挂钩放在所有其他挂钩之后。但是,这是一个问题,因为我想用查询数据中的值填充一些状态值。

// code that doesn't error, but am not able to initialize state with query values

const [url, setUrl] = useState('')

const updateLink = useMutation(LINK_UPDATE_MUTATION, {
  variables: {
    id: props.id,
    url
  }
})

const { data, loading, error } = useQuery(LINK_QUERY, {
  variables: {
    id: props.id
  }
})

if (loading) {
  return <div>Loading...</div>
}
if (error) {
  return <div>Error! {error.message}</div>
}

vs

// code that errors with 'Rendered more hooks than during the previous render.'

const { data, loading, error } = useQuery(LINK_QUERY, {
    variables: {
      id: props.id
    }
  })

  if (loading) {
    return <div>Loading...</div>
  }
  if (error) {
    return <div>Error! {error.message}</div>
  }

const updateLink = useMutation(LINK_UPDATE_MUTATION, {
    variables: {
      id: props.id,
      url
    }
  })

const [url, setUrl] = useState(data.link.url)

我希望可以使用useQuery挂钩以其查询数据初始化其他值的方式。

如果代码不足或需要更多说明,请告诉我。谢谢。

2 个答案:

答案 0 :(得分:1)

您需要做的是在第一个挂钩导致响应时更新状态。为此,您可以使用useEffect钩子。您需要将所有挂钩都呈现在功能组件的顶部。

const [url, setUrl] = useState('')

const updateLink = useMutation(LINK_UPDATE_MUTATION, {
  variables: {
    id: props.id,
    url
  }
})

const { data, loading, error } = useQuery(LINK_QUERY, {
  variables: {
    id: props.id
  }
})

useEffect(() => {
  if(data && data.link) {
    setUrl(data.link.url);
  }
}, [data])

if (loading) {
  return <div>Loading...</div>
}
if (error) {
  return <div>Error! {error.message}</div>
}

答案 1 :(得分:-1)

你可以简单地按照这个apprch,我也是这样做的。

  const client = useApolloClient();
  const [newData, setNewData] = useState(null);
  const [loading, setLoading] = useState(false);

  async function runQuery() {
    setLoading(true);

    const useQueryData = await client.query({
      query: SUBMITTED_ASSIGNMENTS, variables: {
        userId
      }
    });
    setNewData(useQueryData?.data?.assignments);
    console.log('newData', newData);
    setLoading(false);
  }

  useEffect(() => {
    runQuery();
  }, [newData]);