@@ -225,53 +225,95 @@ This pattern allows you to build complex functionality by composing simpler mixi
225225
226226State mixins are particularly useful for:
227227
228- - ** Authentication ** : Shared login/logout functionality
229- - ** Validation ** : Common form validation logic
228+ - ** Form Validation ** : Shared validation logic across forms
229+ - ** UI State Management ** : Common modal, loading, or notification patterns
230230- ** Logging** : Centralized logging and debugging
231231- ** API Integration** : Shared HTTP client functionality
232- - ** UI State ** : Common modal, loading, or notification patterns
232+ - ** Data Formatting ** : Consistent data presentation across components
233233
234234``` python demo exec
235- class AuthMixin (rx .State , mixin = True ):
236- is_authenticated: bool = False
237- username: str = " "
235+ class ValidationMixin (rx .State , mixin = True ):
236+ errors: dict[ str , str ] = {}
237+ is_loading: bool = False
238238
239239 @rx.event
240- def login (self , username : str ):
241- # Simplified login logic
242- self .username = username
243- self .is_authenticated = True
240+ def validate_email (self , email : str ) -> bool :
241+ if " @" not in email or " ." not in email:
242+ self .errors[" email" ] = " Invalid email format"
243+ return False
244+ self .errors.pop(" email" , None )
245+ return True
244246
245247 @rx.event
246- def logout (self ):
247- self .username = " "
248- self .is_authenticated = False
248+ def validate_required (self , field : str , value : str ) -> bool :
249+ if not value.strip():
250+ self .errors[field] = f " { field.title()} is required "
251+ return False
252+ self .errors.pop(field, None )
253+ return True
249254
250- class DashboardState (AuthMixin , rx .State ):
251- dashboard_data: list[str ] = []
255+ @rx.event
256+ def clear_errors (self ):
257+ self .errors = {}
252258
253- @rx.var
254- def welcome_message (self ) -> str :
255- return rx.cond(
256- self .is_authenticated,
257- f " Welcome, { self .username} ! " ,
258- " Please log in"
259- )
260-
261- def auth_example ():
259+ class ContactFormState (ValidationMixin , rx .State ):
260+ name: str = " "
261+ email: str = " "
262+ message: str = " "
263+
264+ @rx.event
265+ def submit_form (self ):
266+ self .clear_errors()
267+ valid_name = self .validate_required(" name" , self .name)
268+ valid_email = self .validate_email(self .email)
269+ valid_message = self .validate_required(" message" , self .message)
270+
271+ if valid_name and valid_email and valid_message:
272+ self .is_loading = True
273+ yield rx.sleep(1 )
274+ self .is_loading = False
275+ self .name = " "
276+ self .email = " "
277+ self .message = " "
278+
279+ def validation_example ():
262280 return rx.vstack(
263- rx.text(DashboardState.welcome_message),
281+ rx.heading(" Contact Form" ),
282+ rx.input(
283+ placeholder = " Name" ,
284+ value = ContactFormState.name,
285+ on_change = ContactFormState.set_name,
286+ ),
264287 rx.cond(
265- DashboardState.is_authenticated,
266- rx.button(" Logout" , on_click = DashboardState.logout),
267- rx.hstack(
268- rx.input(placeholder = " Username" , on_blur = DashboardState.login),
269- rx.text(" (Enter username to login)" ),
270- spacing = " 2" ,
271- ),
288+ ContactFormState.errors.contains(" name" ),
289+ rx.text(ContactFormState.errors[" name" ], color = " red" ),
290+ ),
291+ rx.input(
292+ placeholder = " Email" ,
293+ value = ContactFormState.email,
294+ on_change = ContactFormState.set_email,
295+ ),
296+ rx.cond(
297+ ContactFormState.errors.contains(" email" ),
298+ rx.text(ContactFormState.errors[" email" ], color = " red" ),
299+ ),
300+ rx.text_area(
301+ placeholder = " Message" ,
302+ value = ContactFormState.message,
303+ on_change = ContactFormState.set_message,
304+ ),
305+ rx.cond(
306+ ContactFormState.errors.contains(" message" ),
307+ rx.text(ContactFormState.errors[" message" ], color = " red" ),
308+ ),
309+ rx.button(
310+ " Submit" ,
311+ on_click = ContactFormState.submit_form,
312+ loading = ContactFormState.is_loading,
272313 ),
273314 spacing = " 4" ,
274315 align = " center" ,
316+ width = " 300px" ,
275317 )
276318```
277319
0 commit comments