diff --git a/docs/examples/InvalidateQuery.jsx b/docs/examples/InvalidateQuery.jsx
new file mode 100644
index 0000000..64de88b
--- /dev/null
+++ b/docs/examples/InvalidateQuery.jsx
@@ -0,0 +1,75 @@
+import { bind, Subscribe } from "@react-rxjs/core"
+import { createSignal } from "@react-rxjs/utils"
+import React, { useRef } from "react"
+import { concat, of } from "rxjs"
+import { concatMap, switchMap } from "rxjs/operators"
+
+const { getTodos, postTodo } = (() => {
+ let todos = [
+ {
+ id: 0,
+ title: "Grocery shopping",
+ },
+ ]
+
+ return {
+ getTodos: async () => todos,
+ postTodo: async (todo) => {
+ todos = [
+ ...todos,
+ {
+ id: todos[todos.length - 1].id + 1,
+ title: todo
+ },
+ ]
+ },
+ }
+})()
+
+const [todoPost$, addTodo] = createSignal()
+
+const todoResult$ = todoPost$.pipe(concatMap(postTodo))
+
+const [useTodos] = bind(
+ // When do we need to request todos?
+ concat(
+ // 1. One single time when starting
+ of(null),
+ // 2. Every time we have created a new todo
+ todoResult$
+ ).pipe(
+ switchMap(getTodos),
+ )
+)
+
+function Todos() {
+ const ref = useRef()
+ const todos = useTodos()
+
+ const handleAddClick = () => {
+ addTodo(ref.current.value);
+ ref.current.value = ''
+ ref.current.focus()
+ }
+
+ return (
+
+
+
+
+
+ {todos.map((todo) => (
+ - {todo.title}
+ ))}
+
+
+ )
+}
+
+export default function InvalidateQuery() {
+ return (
+ Loading...}>
+
+
+ )
+}
diff --git a/docs/quick-start.md b/docs/quick-start.md
index 0852cb5..8ddd6a0 100644
--- a/docs/quick-start.md
+++ b/docs/quick-start.md
@@ -79,7 +79,7 @@ function CharacterCounter() {
}
```
-The interactive result:
+### Interactive result
{() => }
diff --git a/docs/recipes/invalidate-query.md b/docs/recipes/invalidate-query.md
new file mode 100644
index 0000000..7bbf839
--- /dev/null
+++ b/docs/recipes/invalidate-query.md
@@ -0,0 +1,73 @@
+---
+title: Invalidate Query
+---
+
+import InvalidateQuery from "../examples/InvalidateQuery"
+import BrowserOnly from '@docusaurus/BrowserOnly';
+
+```tsx
+import { bind, Subscribe } from "@react-rxjs/core"
+import { createSignal } from "@react-rxjs/utils"
+import { concat, of } from "rxjs"
+import { concatMap, switchMap } from "rxjs/operators"
+import { getTodos, postTodo } from "../my-api"
+
+const [todoPost$, addTodo] = createSignal()
+
+const todoResult$ = todoPost$.pipe(
+ concatMap(postTodo)
+)
+
+const [useTodos] = bind(
+ // When do we need to request todos?
+ concat(
+ // 1. One single time when starting
+ of(null),
+ // 2. Every time we have created a new todo
+ todoResult$
+ ).pipe(
+ switchMap(getTodos),
+ )
+)
+
+function Todos() {
+ const ref = useRef()
+ const todos = useTodos()
+
+ const handleAddClick = () => {
+ addTodo(ref.current.value);
+ ref.current.value = ''
+ ref.current.focus()
+ }
+
+ return (
+
+
+ {todos.map((todo) => (
+ - {todo.title}
+ ))}
+
+
+
+
+ )
+}
+
+function App() {
+ return (
+ Loading...}>
+
+
+ )
+}
+```
+
+### Interactive result
+
+
+ {() => }
+
diff --git a/sidebars.js b/sidebars.js
index b530fb3..8ff77d4 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -1,6 +1,7 @@
module.exports = {
someSidebar: {
Introduction: ["motivation", "quick-start", "features"],
+ Recipes: ["recipes/invalidate-query"],
"API Reference": [
{
type: "category",