使用 React Hooks 通过 RTK 查询链 query/mutation 次调用
Chain query/mutation calls with RTK Query using React Hooks
在下面的示例中,我尝试使用 React 和 Redux Toolkit 创建一个简单的 login/authentication 组件。
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
查询,因此我没有 getUser
中的 isLoading
属性 可用于组件的其余部分。
但是如果我想使用 React Hooks 进行调用,我需要事先从 login
突变中得到结果。
const [getUser, { isLoading: isUserLoading }] = useGetUserQuery(resultFromLoginMutation);
而且我不知道该怎么做。一个接一个,这样我就可以利用两个 isLoading
属性。
您可以使用 skipToken
或 skip
选项:
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);
在下面的示例中,我尝试使用 React 和 Redux Toolkit 创建一个简单的 login/authentication 组件。
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
查询,因此我没有 getUser
中的 isLoading
属性 可用于组件的其余部分。
但是如果我想使用 React Hooks 进行调用,我需要事先从 login
突变中得到结果。
const [getUser, { isLoading: isUserLoading }] = useGetUserQuery(resultFromLoginMutation);
而且我不知道该怎么做。一个接一个,这样我就可以利用两个 isLoading
属性。
您可以使用 skipToken
或 skip
选项:
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);