What are Rx Types in GetX?
Rx types are the building blocks of reactive state management in GetX. They are observable variables that notify the UI whenever their value changes. GetX provides specialized Rx classes for primitive types, collections, and any custom type through the generic Rx<T>.
- Primitive Rx Types
GetX offers dedicated Rx types for common primitive types, each with optimized performance and helpful methods.
- Collection Rx Types
GetX provides reactive collections that automatically notify UI when items are added, removed, or modified.
- Generic Rx Type (Rx<T>)
For custom classes, use the generic Rx<T> type. This allows you to make any object reactive.
- Accessing and Modifying Values
Each Rx type has a .value getter/setter to access or change the underlying value. For collections, you can also use collection methods directly.
- Useful Rx Methods
Rx types come with built-in methods to simplify common operations.
value– Get or set the current value.refresh()– Manually notify listeners (useful after modifying nested properties).assign(T value)– Replace the entire value (works for all Rx types).assignAll(Iterable<T> iterable)– Replace collection contents with another iterable (for RxList/RxSet).update(void Function(T) fn)– Modify the value inside a callback and automatically notify listeners.bindStream(Stream<T> stream)– Bind an Rx variable to a stream, updating automatically when stream emits.call()– Shortcut for.value(e.g.,count()instead ofcount.value).
- Working with Streams
Rx types can be easily connected to streams, making them perfect for real-time data.
- Rx Types with Workers
Workers can listen to Rx variables to react to changes, log, or trigger side effects.
- Converting Rx to Non-Rx
Sometimes you need to access the raw value without reactivity. Use .value to get the underlying value.
- Performance Tips
- Use primitive Rx types for simple values – they're lightweight.
- Avoid large objects in Rx – break them into smaller reactive pieces if possible.
- Use
updatefor nested modifications – it's cleaner and ensures notifications. - Batch modifications – when updating a collection with many changes, consider using
assignorassignAllinstead of multiple add/remove calls. - Use
refresh()sparingly – preferupdateor direct value assignment to maintain automatic notifications.
- Common Mistakes
- ❌ Modifying nested properties without refreshing – UI doesn't update.
✅ Use
updatemethod or callrefresh()after modification. - ❌ Using
.obsinside build method – Creates new reactive variables on each rebuild. ✅ Declare Rx variables in controllers only. - ❌ Assigning a new list without triggering update –
items = newListwon't work because items is a getter; useitems.value = newListoritems.assignAll(newList). - ❌ Not using
.valuewhen needed –print(count)might print the RxInt wrapper, not the number. Useprint(count.value). - ❌ Comparing Rx values with
==–if (count == 0)might not work as expected. Compare usingcount.value == 0.
FAQ
- Q: What's the difference between
RxIntandint.obs?
A:int.obsis syntactic sugar that returns anRxInt. They are functionally identical. - Q: Can I use
RxListwith custom objects?
A: Yes,RxList<User>works perfectly. Ensure your objects are immutable or you callrefresh()after modifying them. - Q: How do I make a primitive reactive without
.obs?
A: You can useRxInt(0),RxString(''), etc., but.obsis the recommended concise syntax. - Q: Why doesn't my UI update when I change a property of a custom object?
A: Because the Rx variable is observing the object reference, not its properties. Useupdateor reassign the whole object. - Q: What is the
call()method?
A: It's a shorthand for.value. For example,count()returns the current value. This is useful in Obx where you can writeText('${controller.count()}'). - Q: Can I use
Rxwith enums?
A: Yes,Rx<MyEnum>(MyEnum.value1)works perfectly. - Q: How do I dispose of Rx variables?
A: They are automatically disposed when the controller is disposed. You don't need to manually clean them up. - Q: Can I use Rx types outside of GetX controllers?
A: Yes, you can, but then you lose automatic lifecycle management. It's better to keep them inside controllers.
Conclusion
Rx types are the heart of GetX's reactive system. By mastering RxInt, RxString, RxList, RxMap, and the generic Rx<T>, you can build highly responsive Flutter applications. Combine them with workers and best practices for a clean, scalable architecture.