使用React Hooks和RTK Query链式查询/变异调用

3
在下面的示例中,我试图使用React和Redux Toolkit创建一个简单的登录/身份验证组件。
const Login = () => {
    const dispatch = useDispatch();
    const [login, { isLoading }] = useLoginMutation();
    const [loginData, setLoginData] = useState({
        email: '',
        password: '',
    });

    const loginHandler = async () => {
        try {
            const result = await login({
                email: loginData.email,
                password: loginData.password,
            }).unwrap();

            const { token, userId } = result;

            const { data } = await dispatch(
                backendApi.endpoints.getUser.initiate({ token, userId })
            );

            dispatch(
                setCredentials({
                    user: {
                        email: data.user.email,
                        id: data.user.id,
                        name: data.user.name,
                        type: data.user.type,
                    },
                    token,
                })
            );
        } catch (err) {
            console.log(err);
        }
    };

    return (
        <Space>
            {isLoading ? (
                <SpinnerIcon />
            ) : (
                // setLoginData and loginHandler are set and used here
                // Standard React code: Input onChange -> setLoginData / Submit button onClick -> loginHandler
                // (nothing special, code shortened for the sake of readability)
                <FormWithEmailPasswordInputsAndButton />
            )}
        </Space>
    );
};

这段代码运行良好,但问题在于:

我想利用getUser查询结果对象上的isLoading属性,以便在两个请求都完成之前,<SpinnerIcon />组件可见。

目前spinnerIcon组件仅在login API调用期间显示,因为我没有使用React Hooks调用getUser查询,所以没有将isLoading属性从getUser传递到组件的其他部分。

但如果我想使用React Hooks进行调用,我需要先得到login变异的结果。

const [getUser, { isLoading: isUserLoading }] = useGetUserQuery(resultFromLoginMutation);

我不知道该如何做。请让这两个请求依次执行,这样我就可以同时利用两个isLoading属性。

1个回答

5
您可以使用skipTokenskip选项:

const [login, { isLoading, data: resultFromLoginMutation, isSuccess }] = useLoginMutation();
const [getUser, { isLoading: isUserLoading }] = useGetUserQuery(resultFromLoginMutation, { skip: !isSuccess });

或者

const [login, { isLoading, data: resultFromLoginMutation }] = useLoginMutation();
const [getUser, { isLoading: isUserLoading }] = useGetUserQuery(resultFromLoginMutation ?? skipToken);

1
感谢@phry,只有一个警告,useQuery钩子似乎不返回数组,所以我必须这样调用它:const { isLoading: isUserLoading, data: resultFromGetUserQuery } = useGetUserQuery( resultFromLoginMutation, { skip: !isSuccess, } ); - Gustavo Maximo
然而,我仍然在resultFromLoginMutation上遇到了TS错误: “类型'authData | undefined'的参数无法分配给类型'authData | unique symbol'的参数。 类型'undefined'无法分配给类型'authData | unique symbol'。ts(2345)”因为当它传递给useGetUserQuery时,resultFromLoginMutation可能是未定义的。有什么想法如何解决它? - Gustavo Maximo
还有,感谢你的YouTube视频,它们真的很有帮助。在发布这个问题到SO之前,我考虑给你写一封电子邮件,但觉得那样可能会有点打扰,而且我看到你在SO上非常活跃,所以我有一种感觉你最终会出现哈哈哈。 - Gustavo Maximo
2
至于您当前的错误:您可能希望走“?? skipToken”路线-这与TS更兼容。 - phry
如果您有问题,最好的选择是在SO、github的RTK“讨论”部分或Reactiflux的redux聊天中寻求帮助。那里也有许多RTKQ用户。 - phry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接