在异步数据中使用 useState 时避免非空断言的方法?

Way to avoid non-null assertion while using useState in async Data?

尝试将严格的打字稿与 Next.js 和 React-query

结合使用

useQuery 的 return 数据有问题 Post |不明确的。 所以我应该让 useQuery 给出的数据不为 null !运算符同时分配给 useState

ESlint 不喜欢非空类型断言。 我知道我可以将其关闭...但是我想进行严格的类型检查所以我不想避免这种情况。

我发现的一种方法是使用 if 语句进行空检查 但是 React Hooks 无法用 if 语句包装它...

有什么绝妙的方法吗?

我的代码是这样的

const Edit = () => {
    const router = useRouter();
    const { id } = router.query;

    const { data } = useQuery<Post>('postEdit', () => getPost(id as string));

    const [post, setPost] = useState<TitleAndDescription>({
        title: data!.title,
        content: data!.content,
    });
    const editMutation = usePostEditMutation();
    return (
        <MainLayout>
            <Wrapper>
                {data && <Editor post={post} setPost={setPost} />}
            </Wrapper>
        </MainLayout>
    );
};

export interface TitleAndDescription {
    title: string;
    content: Descendant[];
}

你可以做到

const [post, setPost] = useState<TitleAndDescription>({
    title: data?.title ?? '',
    content: data?.content ?? []
});

非空断言适用于您希望从类型中排除空值或未定义值的情况。大多数情况下你不需要它,你可以转换成你想要的类型:

(data as Post).title

或提供备用值:

data?.title || ''

虽然你可以这样做:

const [post, setPost] = useState<TitleAndDescription>({
    title: data?.title ?? '',
    content: data?.content ?? []
});

正如当前接受的答案所暗示的那样,它不会解决您的问题,因为您将始终在本地状态中拥有 undefined,因为当新数据来自 useQuery 时它不会自动更新。 data 在第一次渲染时将是未定义的,因为 react-query 需要先获取它。使用 useState,您只传递第一个渲染的初始值 - 这是未定义的。

无需将数据从 react-query 复制到本地状态。这只是复制了单一的事实来源。您可以只使用从 useQuery 返回的数据,因为它始终反映服务器值:

 const { data } = useQuery<Post>('postEdit', () => getPost(id as string));
const post = data ?? { title: '', content: [] }