mirror of
https://github.com/Dvorinka/Devour.git
synced 2026-06-04 20:43:05 +00:00
17 lines
8.7 KiB
JSON
17 lines
8.7 KiB
JSON
{
|
|
"id": "b7f33d04d0417c4d19a9c9c1",
|
|
"source": "solid:signals",
|
|
"type": "github-document",
|
|
"title": "fetching-data",
|
|
"content": "---\ntitle: Fetching data\norder: 3\nuse_cases: \u003e-\n api calls, async data loading, server communication, external data fetching,\n loading states, error handling\ntags:\n - data\n - fetching\n - async\n - api\n - createresource\n - suspense\n - loading\nversion: '1.0'\ndescription: \u003e-\n Master data fetching in Solid with createResource for async operations,\n loading states, error handling, and Suspense boundaries.\n---\n\nFor most modern web applications, data fetching is a common task.\nSolid has a built-in utility, `createResource` , that was created to simplify data fetching.\n\n## What is `createResource` ?\n\n`createResource` is a specialized [signal](/concepts/signals) designed specifically for managing asynchronous data fetching.\nIt wraps around the async operations, providing a way to handle various states: loading, success, and error.\n\nThis function is non-blocking, meaning that `createResource` guarantees that the application remains responsive, even during the retrieval of information.\nBecause of this, common pitfalls of traditional async handling, such as unresponsive UIs during data fetching can be avoided.\n\n## Using `createResource`\n\n`createResource` requires a function that returns a promise as its argument.\nUpon the call, `createResource` returns a signal which has reactive properties like loading, error, latest, etc.\nThese properties can be used to conditionally render JSX based on the current reactive state.\n\nThe fetcher function that is created makes a call to get a user, which is then passed in as an argument to `createResource`.\n\nThe signal returned from the `createResource` provides the properties that can assist with conditional rendering based on the current reactive state:\n* `state`: The current status of the operation (`unresolved`, `pending`, `ready`, `refreshing`, or `errored`).\n* `loading`: Indicates that the operation is currently in progress via a `boolean`.\n* `error`: If the operation fails for any reason, this property will contain information about this error.\nIt may be a string with an error message, or an object with more detailed information.\n* `latest`: The most recent data or result returned from the operation.\n\nWhen there is a change in the source signal, an internal fetch process is triggered to retrieve new data based on this change.\n\n```jsx\nimport { createSignal, createResource, Switch, Match, Show } from \"solid-js\";\n\nconst fetchUser = async (id) =\u003e {\n const response = await fetch(`https://swapi.dev/api/people/${id}/`);\n return response.json();\n}\n\nfunction App() {\n const [userId, setUserId] = createSignal();\n const [user] = createResource(userId, fetchUser);\n\n return (\n \u003cdiv\u003e\n \u003cinput\n type=\"number\"\n min=\"1\"\n placeholder=\"Enter Numeric Id\"\n onInput={(e) =\u003e setUserId(e.currentTarget.value)}\n /\u003e\n \u003cShow when={user.loading}\u003e\n \u003cp\u003eLoading...\u003c/p\u003e\n \u003c/Show\u003e\n \u003cSwitch\u003e\n \u003cMatch when={user.error}\u003e\n \u003cspan\u003eError: {user.error}\u003c/span\u003e\n \u003c/Match\u003e\n \u003cMatch when={user()}\u003e\n \u003cdiv\u003e{JSON.stringify(user())}\u003c/div\u003e\n \u003c/Match\u003e\n \u003c/Switch\u003e\n \u003c/div\u003e\n );\n}\n```\n\nWhenever the signal value, `userId`, changes, the internal fetch method `fetchUser` gets triggered.\nThe properties of the `user` resource allow for conditional rendering based on the different states of the fetch process.\n\nThe `Switch/Match` construct provides one way to manage these conditions.\nWhen the fetch succeeds and user data is retrieved, the `user()` condition becomes active, and its related block executes.\nHowever, if there's an error while fetching, the `user.error` block becomes `true`, leading to its corresponding `Match` block being shown.\n\n:::tip\n\nIf you anticipate errors, you may want to wrap `createResource` in an [ErrorBoundary](/reference/components/error-boundary).\n\n:::\n\nIn addition to the `error` property, the `loading` property offers a way to display a loading state to the user during the fetch operation.\n\n## Calling multiple async events\n\nAlthough you can use `createResource` independently, Solid provides an alternative method for synchronizing the display of multiple asynchronous events.\n`Suspense` is a component in Solid designed to act as a boundary.\nIt allows you to display a fallback placeholder while waiting for all asynchronous events to resolve, preventing the display of partially loaded content:\n\n```jsx\nimport { createSignal, createResource, Switch, Match, Suspense } from \"solid-js\";\n\nconst fetchUser = async (id) =\u003e {\n const response = await fetch(`https://swapi.dev/api/people/${id}/`);\n return response.json();\n}\n\nfunction App() {\n const [userId, setUserId] = createSignal();\n const [user] = createResource(userId, fetchUser);\n\n return (\n \u003cdiv\u003e\n \u003cinput\n type=\"number\"\n min=\"1\"\n placeholder=\"Enter Numeric Id\"\n onInput={(e) =\u003e setUserId(e.currentTarget.value)}\n /\u003e\n \u003cSuspense fallback={\u003cdiv\u003eLoading...\u003c/div\u003e}\u003e\n \u003cSwitch\u003e\n \u003cMatch when={user.error}\u003e\n \u003cspan\u003eError: {user.error.message}\u003c/span\u003e\n \u003c/Match\u003e\n \u003cMatch when={user()}\u003e\n \u003cdiv\u003e{JSON.stringify(user())}\u003c/div\u003e\n \u003c/Match\u003e\n \u003c/Switch\u003e\n \u003c/Suspense\u003e\n \u003c/div\u003e\n );\n}\n```\n\n`Suspense` has the ability to identify asynchronous reads within its descendants and act accordingly.\nThis feature helps to remove any intermediate components that may otherwise be displayed during partial loading states.\nAdditionally, you can nest as many components as needed within `Suspense` but only the closest ancestor will switch to the `fallback` state when a loading state is detected.\n\n\u003cEraserLink\n\thref=\"https://app.eraser.io/workspace/maDvFw5OryuPJOwSLyK9?elements=kMt6qc0qF9MlG2K9P28pOQ\"\n\tpreview=\"https://app.eraser.io/workspace/maDvFw5OryuPJOwSLyK9/preview?elements=kMt6qc0qF9MlG2K9P28pOQ\u0026type=embed\"\n/\u003e\n\n## Dynamic data handling\n\nWith the second output of `createResource`, there are 2 powerful methods designed to enhance and simplify some complex aspects of data management:\n\n### `mutate`\n\nIn situations where immediate feedback or responsiveness is important, the `mutate` method offers \"optimistic mutations.\"\nThese mutations provide instant feedback, even while background processes, such as server confirmations, are still in progress.\n\nThis functionality is particularly valuable in applications like task lists.\nFor example, when users input a new task and click the `Add` button, the list will refresh immediately, regardless of the ongoing data communication with the server.\n\n```jsx\nimport { For, createResource } from \"solid-js\"\n\nfunction TodoList() {\n const [tasks, { mutate }] = createResource(fetchTasksFromServer);\n\n return (\n \u003c\u003e\n \u003cul\u003e\n \u003cFor each={tasks()}\u003e\n {(task) =\u003e (\n \u003cli\u003e{task.name}\u003c/li\u003e\n )}\n \u003c/For\u003e\n \u003c/ul\u003e\n \u003cbutton\n onClick={() =\u003e {\n mutate((todos) =\u003e [...todos, \"do new task\"]); // add todo for user\n // make a call to send to database\n }}\n \u003e\n Add Task\n \u003c/button\u003e\n \u003c/\u003e\n );\n}\n```\n\n### `refetch`\n\nWhen real-time feedback is necessary, the `refetch` method can be used to reload the current query regardless of any changes.\nThis method can be particularly useful when data is constantly evolving, such as with real-time financial applications.\n\n```jsx\nimport { createResource, onCleanup } from \"solid-js\"\n\nfunction StockPriceTicker() {\n const [prices, { refetch }] = createResource(fetchStockPrices);\n\n const timer = setInterval(() =\u003e {\n refetch()\n }, 1000);\n onCleanup(() =\u003e clearInterval(timer))\n}\n```",
|
|
"url": "https://github.com/solidjs/solid-docs/blob/HEAD/src/routes/guides/fetching-data.mdx",
|
|
"metadata": {
|
|
"path": "src/routes/guides/fetching-data.mdx",
|
|
"repo": "solidjs/solid-docs",
|
|
"repo_url": "https://github.com/solidjs/solid-docs.git",
|
|
"size": 7589,
|
|
"source_type": "github"
|
|
},
|
|
"hash": "4739b288ec1e7a51fcc2b1e515b352914d5365233de242cd2c8038c99974b5e1",
|
|
"timestamp": "2026-02-23T11:43:00.187728765+01:00"
|
|
} |