# Streaming Props into State URL: /concepts/streaming/streaming-props When working with AI-generated content in Tambo, you often need to update your component state when new content streams in. The `useTamboStreamingProps` hook simplifies this common pattern. ## Building on Previous Concepts This guide combines two key Tambo concepts: 1. **[Streaming](/docs/concepts/streaming)** - The ability to receive AI-generated content in real-time as it's being created 2. **[Component State](/docs/concepts/component-state)** - Tambo's state management for tracking component state as context for AI We recommend you read those first. When using streaming, props arrive incrementally, and you need an efficient way to update your component state without complex useEffect dependencies. `useTamboStreamingProps` solves this exact problem. ## Why this matters React was designed around discrete renders, but large language models deliver **continuous streams** of tokens.\ Trying to glue the two paradigms together with ad-hoc `useEffect` logic quickly leads to: * Duplicate diffing code across components * Oversized dependency arrays that are hard to reason about * Extra re-renders that waste CPU and battery `useTamboStreamingProps` centralises the diffing and batching so your component only re-renders when something **actually** changed. **Real-world numbers:** while streaming at \~4 tokens / sec we measured **\~80 % fewer renders** and **\~65 % less main-thread time** compared with a naive `useEffect` that writes state on every chunk. * **Stale closures** – forgetting to include the latest setter in the dependency array * **Infinite loops** – updating state unconditionally inside an effect that depends on that same state * **Out-of-order writes** – multiple async effects racing to write conflicting values * **Performance hits from excessive renders** – diffing large objects on every chunk * **Missed updates** – early-return logic that skips valid but falsy values ## Using `useTamboStreamingProps` ```tsx import { useTamboComponentState, useTamboStreamingProps, } from "@tambo-ai/react"; function MyComponent({ streamedTitle, streamedBody }) { // 1. Set up your Tambo component state const [state, setState] = useTamboComponentState("myState", { title: "", body: "", }); // 2. Connect streaming props to your state useTamboStreamingProps(state, setState, { title: streamedTitle, body: streamedBody, }); // That's it! Your state will automatically update when props change return (

{state?.title}

{state?.body}

); } ``` ## Benefits * Eliminates repetitive useEffect code * Automatically detects and applies changes * Only updates when values actually change * Works with any state shape * Type-safe with TypeScript ## Without vs With **Before (repetitive pattern):** ```tsx useEffect(() => { if (state) { const shouldUpdateTitle = streamedTitle && streamedTitle !== state.title; const shouldUpdateBody = streamedBody && streamedBody !== state.body; if (shouldUpdateTitle || shouldUpdateBody) { setState({ ...state, title: shouldUpdateTitle ? streamedTitle : state.title, body: shouldUpdateBody ? streamedBody : state.body, }); } } }, [streamedTitle, streamedBody]); ``` **After (clean and simple):** ```tsx useTamboStreamingProps(state, setState, { title: streamedTitle, body: streamedBody, }); ``` Don't want to use Tambo's state management? You can use your own! ```tsx const [state, setState] = useState({ title: "", body: "", }); useTamboStreamingProps(state, setState, { title: streamedTitle, body: streamedBody, }); ``` Works the same, but you don't get the benefits of Tambo's state management. ## When **not** to use `useTamboStreamingProps` * The prop arrives **once** (e.g. static config fetched at build time). * You need **custom reconciliation** that can't be expressed as a shallow merge. * The incoming object is **huge** and diffing would dominate render time. * You already debounce/queue updates **up-stream** (e.g. via a websocket buffer). * You're on React **\< 18** and can't rely on concurrent rendering semantics. ## Glossary * **dependency array** - the second argument to [`useEffect`](https://react.dev/reference/react/useEffect#dependencies) that tells React when the effect should re-run. * **useEffect** - a React hook for performing side-effects after a component render. See the [official docs](https://react.dev/reference/react/useEffect) for details.