reactjs 在写入状态之前等待useQuery

qlvxas9a  于 2022-11-29  发布在  React
关注(0)|答案(1)|浏览(140)

我使用react-query提取数据,由于稍后要进行一些表单编辑,因此需要将其存储在state中。
在表单编辑之前,它运行良好:

import { useQuery } from '@apollo/client';
import { SINGLE_PARTICIPANT_QUERY } from 'queries/participantQueries';
import { ProfileGeneral } from './ProfileGeneral';

const ProfilePage = ({ id }) => {

    const {data, loading, error} = useQuery(SINGLE_PARTICIPANT_QUERY, {
        variables: {
            id
        }
    });

    if (loading) {
        return <div>Loading</div>;
    }
    if (error) {
        return (
            <div>
                {error.message} />
            </div>
        );
    }
    const { participant } =data;
    return (
        <div>
           <ProfileGeneral participant={participant} />
        </div>

但在尝试将其添加到state中后,我不断收到一条错误消息,指示它在数据未准备好的情况下进行渲染。

import { useQuery } from '@apollo/client';
import { SINGLE_PARTICIPANT_QUERY } from 'queries/participantQueries';
import { ProfileGeneral } from './ProfileGeneral';
import { useEffect, useState } from 'react';

const ProfilePage = ({ id }) => {
    const [participant, setParticipant] = useState(null);
    const { data, loading, error } = useQuery(SINGLE_PARTICIPANT_QUERY, {
        variables: {
            id
        }
    });

    useEffect(() => {
        if (data && data.participant) {
            setParticipant(data.participant);
        }
    }, [data, participant]);

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

    return (
        <div>
           <ProfileGeneral participant={participant} />
        </div>

我赶紧回头:

Server Error
TypeError: Cannot read properties of null (reading 'firstName')

This error happened while generating the page. Any console logs will be displayed in the terminal window.

我知道我需要让它等待或在它获得查询的数据后立即重新呈现,但我不确定如何防止它。
感谢您查看!

deyfvvtc

deyfvvtc1#

这是因为:

  1. setParticipant异步地改变状态,
  2. useEffect在渲染实际发生后调用
    因此,即使data.participant不为空,participant为空,直到下一个渲染阶段
    您可以更改为:
const ProfilePage = ({ id }) => {
    //...

    if (loading || !participant) {
        return <div>Loading</div>;
    }

    //...
}

相关问题