@gr.render decorator changes this, allowing you to dynamically create, modify, or remove components based on user interactions.
Dynamic number of components
Let’s start with a simple example that creates a variable number of textboxes:@gr.render decorator enables this with three simple steps:
1
Create a function and add the decorator
Wrap your function with
@gr.render to make it re-render dynamically.2
Specify inputs
Add input components to the
inputs= parameter. The function will automatically re-run when any input changes.3
Create components inside the function
Any components created inside the function will be rendered based on the inputs.
Customizing triggers
By default,@gr.render re-runs on:
- The
.loadevent of the app - The
.changeevent of any input component
If you set custom triggers and want an automatic render at app start, add
demo.load to your list of triggers.Dynamic event listeners
When you create components inside a render function, you can also attach event listeners to them:- Event listeners from the previous render are cleared
- New event listeners from the latest run are attached
- The number of textboxes matches the current
text_countvalue
Understanding the key parameter
Thekey= parameter tells Gradio that the same component is being recreated across re-renders. This provides two benefits:
1
Browser performance
The same DOM element is reused instead of being destroyed and rebuilt, which is faster and preserves browser attributes.
2
Property preservation
Properties that may change (like
value) are preserved across re-renders instead of being reset.value property is preserved. You can specify additional properties with preserved_by_key=:
- When you change the slider, textboxes re-render
- Any entered
valueis preserved (because it’s preserved by default) - Any changed
labelis preserved (because we added it topreserved_by_key) - The
infoproperty resets (because it’s not inpreserved_by_key)
Parent layouts must also be keyed: If your component is nested within layout items like
gr.Row or gr.Column, make sure to key those parent elements as well. The keys of all parent elements must match for the component to be properly preserved.Keying event listeners
You can also key event listeners to improve performance and prevent errors:- The same listener is recreated with the same inputs and outputs across renders
- An event from a previous render might finish after a re-render occurs
Building a todo list app
Let’s put everything together with a complete example:Important pattern: When a variable from a loop is used inside an event listener function, “freeze” it by setting it as a default argument:This ensures each listener uses the correct loop-time value, not the final value after the loop completes.
Working with nested state
When your render function reacts to a list or dict ingr.State:
1
Set state as output
Any event listener that modifies the state must include the state variable as an output, even if the function modifies it in-place. This tells Gradio to check if the state has changed.
2
Freeze loop variables
Use default arguments to freeze variables that are used inside event listeners within loops.
Building an audio mixer
Here’s a more advanced example that demonstrates all the concepts:Using sets for many inputs: When you have many components of different types as inputs, use set notation (
inputs={comp1, comp2, ...}) instead of list notation. In your function, you’ll receive a dictionary where keys are the components and values are their current values.Best practices
1
Always use keys
Key all components and layouts inside render functions to preserve state and improve performance.
2
Freeze loop variables
When using loop variables inside event listeners, freeze them with default arguments:
func(task=task).3
Set state as output
When modifying state variables (especially nested structures), always include them in the event listener’s outputs.
4
Define listeners inside render
Event listeners that use dynamically created components must be defined inside the render function.
5
Key event listeners
Key your event listeners when the same listener is recreated across renders to prevent errors and improve performance.
Next steps
The@gr.render decorator dramatically expands what you can build with Gradio. Now you can:
- Explore custom HTML components for even more flexibility
- Learn about state management for complex applications
- Build multi-step workflows with dynamic layouts