仅在组件第一次以惯用和优雅的方式呈现时执行 react-apollo-hooks useQuery

Rob*_*kal 6 reactjs react-apollo react-apollo-hooks

我正在使用最优秀的react-apollo-hooks 库,特别是 useQuery 钩子:

function Index() {
    ...
    const [dialogOpen, setDialogOpen] = useState({ show: false, id: '0' });
    ...   
    const { data, error } = useQuery(GET_JOBS, { suspend: true });
    if (error) {
        return <div>Error! {error.message}</div>;
    }
    const jobs = data.cxJobs; //This is our data
    ....
    function editCallback(e, more) {
        setDialogOpen({ show: true, id: e });
    }
....
}

Run Code Online (Sandbox Code Playgroud)

当然,一旦我更改了 dialogOpen 状态,组件就会重新渲染并再次执行 graphql 查询。根据对库github repo的建议,我重写了代码以设置一些状态以及 useEffect:

function Index() {
    ...
    const [dialogOpen, setDialogOpen] = useState({ show: false, id: '0' });
    const [jobs, setJobs] = useState([]);

    useEffect(_=> {fetchData()}, []);

    const fetchData = async _ => {
        const result = await client.query({query:GET_JOBS});
        setJobs(get(['data','cxJobs'], result));
    }

    async function onEventChanged(id, event) {
        await mutateOne(client, jobGQL, eventToJob(event));
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

这很好。但我能做得更好吗?

ivp*_*ivp 1

你可以做这样的事情。此外,您可能还希望避免将查询结果设置为 useState 并直接使用数据。

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])
Run Code Online (Sandbox Code Playgroud)

@Robert,我发现你在apollo-hooks github上提出了这个问题。我发现有一个答案可以帮助我解决这个问题,因此也将其添加到此处,以便它可以帮助其他人。