antipatterns.rs 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. //! Example: Antipatterns
  2. //! ---------------------
  3. //!
  4. //! This example shows what *not* to do and provides a reason why a given pattern is considered an "AntiPattern". Most
  5. //! anti-patterns are considered wrong to due performance reasons or violate the "rules" of Dioxus. These rules are
  6. //! borrowed from other successful UI frameworks, and Dioxus is more focused on providing a familiar, ergonomic interface
  7. //! rather than building new harder-to-misuse patterns.
  8. use std::collections::HashMap;
  9. use dioxus::prelude::*;
  10. fn main() {}
  11. /// Antipattern: Iterators without keys
  12. /// -----------------------------------
  13. ///
  14. /// This is considered an anti-pattern for performance reasons. Dioxus must diff your current and old layout and must
  15. /// take a slower path if it can't correlate old elements with new elements. Lists are particularly susceptible to the
  16. /// "slow" path, so you're strongly encouraged to provide a unique ID stable between renders.
  17. ///
  18. /// Dioxus will log an error in the console if it detects that your iterator does not properly generate keys
  19. #[derive(PartialEq, Props)]
  20. struct NoKeysProps {
  21. data: HashMap<u32, String>,
  22. }
  23. static AntipatternNoKeys: FC<NoKeysProps> = |cx| {
  24. // WRONG: Make sure to add keys!
  25. rsx!(in cx, ul {
  26. {cx.data.iter().map(|(k, v)| rsx!(li { "List item: {v}" }))}
  27. });
  28. // Like this:
  29. rsx!(in cx, ul {
  30. {cx.data.iter().map(|(k, v)| rsx!(li { key: "{k}", "List item: {v}" }))}
  31. })
  32. };
  33. /// Antipattern: Deeply nested fragments
  34. /// ------------------------------------
  35. ///
  36. /// This particular antipattern is not necessarily an antipattern in other frameworks but does has a performance impact
  37. /// in Dioxus apps. Fragments don't mount a physical element to the dom immediately, so Dioxus must recurse into its
  38. /// children to find a physical dom node. This process is called "normalization". Other frameworks perform an agressive
  39. /// mutative normalization while Dioxus keeps your VNodes immutable. This means that deepely nested fragments make Dioxus
  40. /// perform unnecessary work. Prefer one or two levels of fragments / nested components until presenting a true dom element.
  41. ///
  42. /// Only Component and Fragment nodes are susceptible to this issue. Dioxus mitigates this with components by providing
  43. /// an API for registering shared state without the ContextProvider pattern.
  44. static Blah: FC<()> = |cx| {
  45. // Try to avoid
  46. rsx!(in cx,
  47. Fragment {
  48. Fragment {
  49. Fragment {
  50. Fragment {
  51. Fragment {
  52. div { "Finally have a real node!" }
  53. }
  54. }
  55. }
  56. }
  57. }
  58. )
  59. };