-
-
Notifications
You must be signed in to change notification settings - Fork 9.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot get react-query (useQuery hook) to work with Storybook with external API #12489
Comments
@sdivelbiss i've kept track of your issue while i was working on getting Storybook and React Query working nicely with Axios. Here's what i did:
import React from 'react'
import { ReactQueryCacheProvider, QueryCache } from "react-query";
import { ReactQueryDevtools } from "react-query-devtools";
const queryCache = new QueryCache();
export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
};
/**
* adds a Storybook decorator to get the cache and dev tools showing for each story
*/
export const decorators=[
(story) => (
<ReactQueryCacheProvider queryCache={queryCache}>
{story()}
<ReactQueryDevtools />
</ReactQueryCacheProvider>
),
]
// get the mocked handlers (endpoints) and starts the service worker
if (typeof global.process === 'undefined') {
const { worker } = require("../src/mocks/workers");
worker.start();
}
import React from "react";
import Axios from "axios";
import { useQuery } from "react-query";
/**
* Component to demonstrate how to mock data (GET request) with react-query and axios
*
*/
const AxiosRestExample = () => {
// use query to fetch something with axios out of the url (this case a mocked one)
const { data, error, isLoading } = useQuery("rest-ricky", async () => {
const { data } = await Axios.get("/ricky-rest");
return data;
});
if (isLoading) return <h1>Loading...Go grab a coffee</h1>;
if (error) {
return (
<>
<h2>Upsy daisy something went wrong</h2>
<h2>{error.message}</h2>
</>
);
}
return (
<div>
<h1>{data.name}</h1>
<p>{data.description}</p>
</div>
);
};
export default AxiosRestExample;
import React from "react";
import AxiosRestExample from "./AxiosRestExample";
export default {
title: "React Query Rest (AXIOS) GET Example",
component: AxiosRestExample,
};
const Template = (args) => <AxiosRestExample {...args} />;
export const Default = Template.bind();
import React, { useState } from "react";
import Axios from "axios";
import { useMutation } from "react-query";
import PropTypes from "prop-types";
/**
* function to send something to the url
* @param {String} textValue
*/
async function SendMessage({ textValue }) {
try {
const { data } = await Axios.post("/ricky-post", {
item: textValue,
});
return data;
} catch (error) {
console.log(`SEND MESSAGE ERROR:${error}`);
}
}
/**
* Component to demonstrate how to mock data (POST request) with react-query and axios
* @param {String} initialvalue a dummy prop for the component
*/
const AxiosRestPostExample = ({ initialvalue }) => {
const [textValue, setTextValue] = useState(initialvalue);
const [mutate, { status, error }] = useMutation(SendMessage, {
onSuccess: () => {
console.log("POSTED SOMETHING");
},
onError: () => {
console.log(`SOMETHING WENT WRONG:\n${error}`);
},
});
return (
<div>
<input value={textValue} onChange={(e) => setTextValue(e.target.value)} />
<button
onClick={() => mutate({ textValue })}
disabled={status === "loading" || !textValue}
>
Post something
</button>
</div>
);
};
AxiosRestPostExample.propTypes = {
initialvalue: PropTypes.string,
};
AxiosRestPostExample.defaultProps = {
initialvalue: "Ricky Sanchez",
};
export default AxiosRestPostExample;
import React from "react";
import AxiosRestPostExample from "./AxiosRestPostExample";
export default {
component: AxiosRestPostExample,
title: " React Query Rest Post Example with Axios",
};
const Template = (args) => <AxiosRestPostExample {...args} />;
export const Default = Template.bind({});
export const WithRandomItem = Template.bind({});
WithRandomItem.args = {
initialvalue: "Oingo Boingo",
};
import { setupWorker } from 'msw'
import { handlers } from './handlers'
// This configures a Service Worker with the given request handlers.
export const worker = setupWorker(...handlers)
import { rest } from "msw";
/**
* a list of handlers (endpoints) to emulate (mock) a actual implementation
*/
export const handlers = [
rest.get("/ricky-rest", (req, res, ctx) => {
return res(
ctx.status(200),
ctx.json({
name: "Rick Sanchez",
description: "Scientist extraordinaire",
})
);
}),
rest.post("/ricky-post", (req, res, ctx) => {
const {item}= req.body
return res(
ctx.status(200),
ctx.json({
message: `hey hey ${item}`,
})
);
}),
];
I know that this is a rather small and possibly skewed approach to the problem. But it seems that Storybook and React-Query will work fine together. If you can provide additional information about how you're implementing the associated story file and how you've setup Axios we could take a look at it and probably provide you with a more concrete answer. Or i can hoist up this small reproduction to a repo and you can take a look at it in your time. Let us know and we'll move from there. Stay safe |
Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks! |
@jonniebigodes thanks for this! A couple of questions where I've hit stumbling blocks, if you don't mind. Two, with that change, the msw service worker won't register. Thanks in advance. EDIT (answering myself):
Service Worker successfully created! |
Closing this as we have already documentation within the Build Pages with Storybook docs. The same pattern can be applied. |
I think @jonniebigodes answer will be perfect for most scenarios but there is a problem if you're using something like Firebase where the back-end endpoints are hard to track not like a regular API. Does anyone have a suggestion about this case? I think we can mock the data of the query by using |
Maybe my question is not exactly regards this topic, but may be someone can answer. The case when I need to show only the loading state from react-query, what should I do in this case? |
@Arahis the above is now mostly replaced by msw-storybook-addon. To simulate loading you can create a story like this: export const Loading = Template.bind({});
Loading.parameters = {
msw: {
handlers: [
rest.get("http://localhost:3000/endpoint", (req, res, ctx) => {
return res(ctx.status(200), ctx.json({}), ctx.delay("infinite"));
}),
],
},
}; Although you do have to be careful, because React Query will now be going to the cache for this infinite wait, which might mess your other stories up! I bypass this behaviour by setting cacheTime to 0 when setting up the mock query client: const mockedQueryClient = new QueryClient({
defaultOptions: {
queries: {
retry: false,
cacheTime: 0,
},
},
});
const Template: ComponentStory<typeof YourThing> = () => (
<QueryClientProvider client={mockedQueryClient}>
<YourThing/>
</QueryClientProvider>
); |
Sorry for my bad english but this answer doesn't work
but the console in firefox and chrome said
I tried with Mock Service Worker and execute in another discution mentioned the same problem but the solution doesnt work #Service Worker script does not exist at the given path Please help me to create correct mock my
My component is :
the hook is next:
and storybook is
Why |
if you're using suspense, you need to manually set the
|
I am using storybook to develop my react components in isolation. I am running into an issue with using react-query (useQuery) with storybook. Implementing the component in the app, I get no errors and things work as expected.
I have a custom react hook useSearchStationsByCallLetter that returns the useQuery hook. React-query should be using searchStationsByCallLetter as the api call. ApiService and makeApiCall are a custom axios setup.
The error I get in storybook is:
Desktop (please complete the following information):
The text was updated successfully, but these errors were encountered: