Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[Feature Request] Add useAcross() hook for cross-method data sharing #478

Copy link
Copy link
@yuluyao

Description

@yuluyao
Issue body actions

[Feature Request] Add useAcross() hook for cross-method data sharing

Problem Statement

When decomposing UI into multiple methods within a HookWidget, there's often a need to share values across different methods. Current solutions have their own limitations:

Current Solutions and Their Problems:

1. Method Parameter Passing

class MyWidget extends HookWidget {
  @override
  Widget build(BuildContext context) {
    final controller = useTextEditingController();
    final focusNode = useFocusNode();
    
    return Column(
      children: [
        _buildInput(controller, focusNode),  // Too many parameters
        _buildButtons(controller, focusNode), // Repetitive passing
      ],
    );
  }
  
  Widget _buildInput(TextEditingController controller, FocusNode focusNode) { ... }
  Widget _buildButtons(TextEditingController controller, FocusNode focusNode) { ... }
}

Problems: Long parameter lists, repetitive passing, difficult to maintain

2. Inlining methods into build

Widget build(BuildContext context) {
  final controller = useTextEditingController();
  final focusNode = useFocusNode();
  
  return Column(
    children: [
      // All UI logic crammed into build method, hard to read
      TextField(controller: controller, focusNode: focusNode),
      Row(
        children: [
          ElevatedButton(onPressed: () => controller.clear(), ...),
          ElevatedButton(onPressed: () => focusNode.requestFocus(), ...),
        ],
      ),
    ],
  );
}

Problems: Bloated build method, poor readability, defeats the purpose of method decomposition

Proposed Solution: useAcross() Hook

useAcross allows sharing hook values across different methods within the same HookWidget without parameter passing:

typedef _Holder = ({
  TextEditingController controller,
  FocusNode focusNode,
  ValueNotifier<bool> isValid,
});

class MyWidget extends HookWidget {
  @override
  Widget build(BuildContext context) {
    final controller = useTextEditingController();
    final focusNode = useFocusNode();
    
    // Store all hooks that need to be shared
    useAcross<_Holder>((
      controller: controller,
      focusNode: focusNode,
    ));
    
    return Column(
      children: [
        _buildInput(),      // No parameter passing needed
        _buildButton(),    // Clean and simple
      ],
    );
  }
  
  Widget _buildInput() {
    final _Holder(:controller, :focusNode) = useAcross<_Holder>();
    return TextField(controller: controller, focusNode: focusNode);
  }
  
  Widget _buildButton() {
    final _Holder(:controller) = useAcross<_Holder>();
    return Row(
      children: [
        ElevatedButton(onPressed: () => controller.clear(), ...),
      ],
    );
  }
}

Implementation

T useAcross<T>([T? value]) {
  final context = useContext();
  if (value != null) {
    _container[context] = value;
    return value;
  } else {
    return _container[context] as T;
  }
}

final Expando _container = Expando();
fior-di-latte and morebytesyang-lile and wagner1343

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    Morty Proxy This is a proxified and sanitized view of the page, visit original site.