react_hooks 1.0.0 copy "react_hooks: ^1.0.0" to clipboard
react_hooks: ^1.0.0 copied to clipboard

A Flutter package that provides React-like hooks (useState, useEffect) for state management and side effects in Flutter apps.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:react_hooks/react_hooks.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'React Hooks Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const HomePage(),
    );
  }
}

/// Home page - Simple navigation
class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('React Hooks Demo'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: () => Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => const BasicExample()),
              ),
              child: const Text('Basic useState Example'),
            ),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: () => Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => const ContextExample()),
              ),
              child: const Text('useContext Example'),
            ),
          ],
        ),
      ),
    );
  }
}

// =============================================================================
// Basic useState Example
// =============================================================================

class BasicExample extends HookWidget {
  const BasicExample({super.key});

  @override
  Widget build(BuildContext context) {
    final countState = useState(0);
    
    useEffect(() {
      print('Count: ${countState.value}');
      return null;
    }, [countState.value]);
    
    return Scaffold(
      appBar: AppBar(title: const Text('useState Example')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Count: ${countState.value}', style: const TextStyle(fontSize: 24)),
            const SizedBox(height: 20),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: () => countState.setValue(countState.value - 1),
                  child: const Text('-'),
                ),
                const SizedBox(width: 20),
                ElevatedButton(
                  onPressed: () => countState.setValue(0),
                  child: const Text('Reset'),
                ),
                const SizedBox(width: 20),
                ElevatedButton(
                  onPressed: () => countState.setValue(countState.value + 1),
                  child: const Text('+'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

// =============================================================================
// useContext Example
// =============================================================================

/// User data model
class User {
  final String name;
  final int age;
  
  const User({required this.name, required this.age});
  
  User copyWith({String? name, int? age}) {
    return User(
      name: name ?? this.name,
      age: age ?? this.age,
    );
  }
}

/// Counter context value
class CounterContextValue {
  final int count;
  final void Function() increment;
  final void Function() decrement;
  final void Function() reset;
  
  CounterContextValue({
    required this.count,
    required this.increment,
    required this.decrement,
    required this.reset,
  });
}

/// User context value
class UserContextValue {
  final User user;
  final void Function(String) setName;
  final void Function(int) setAge;
  
  UserContextValue({
    required this.user,
    required this.setName,
    required this.setAge,
  });
}

/// Combined context value
class AppContextValue {
  final CounterContextValue counter;
  final UserContextValue user;
  
  AppContextValue({
    required this.counter,
    required this.user,
  });
}

/// useCounter custom hook
CounterContextValue useCounter([int initialValue = 0]) {
  final countState = useState(initialValue);
  
  void increment() => countState.update((prev) => prev + 1);
  void decrement() => countState.update((prev) => prev - 1);
  void reset() => countState.setValue(initialValue);
  
  return CounterContextValue(
    count: countState.value,
    increment: increment,
    decrement: decrement,
    reset: reset,
  );
}

/// useUser custom hook
UserContextValue useUser([User? initialUser]) {
  final userState = useState<User>(initialUser ?? const User(name: 'John Doe', age: 25));
  
  void setName(String name) {
    userState.setValue(userState.value.copyWith(name: name));
  }
  
  void setAge(int age) {
    userState.setValue(userState.value.copyWith(age: age));
  }
  
  return UserContextValue(
    user: userState.value,
    setName: setName,
    setAge: setAge,
  );
}

/// Context example main page
class ContextExample extends HookWidget {
  const ContextExample({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('useContext Example')),
      body: HookProvider<AppContextValue>(
        create: () => AppContextValue(
          counter: useCounter(0),
          user: useUser(),
        ),
        child: const Column(
          children: [
            Expanded(child: HeaderComponent()),
            Expanded(child: CounterDisplay()),
            Expanded(child: UserDisplay()),
            Expanded(child: UserControls()),
            Expanded(child: CounterControls()),
          ],
        ),
      ),
    );
  }
}

/// Parent component - Header
class HeaderComponent extends HookWidget {
  const HeaderComponent({super.key});

  @override
  Widget build(BuildContext context) {
    return const Center(
      child: Text(
        'Context Example: Counter + User',
        style: TextStyle(fontSize: 20),
      ),
    );
  }
}

/// Child component - Display counter
class CounterDisplay extends HookWidget {
  const CounterDisplay({super.key});

  @override
  Widget build(BuildContext context) {
    final app = useContext<AppContextValue>(context);
    
    return Center(
      child: Text(
        'Count: ${app.counter.count}',
        style: const TextStyle(fontSize: 24),
      ),
    );
  }
}

/// Child component - Display user info
class UserDisplay extends HookWidget {
  const UserDisplay({super.key});

  @override
  Widget build(BuildContext context) {
    final app = useContext<AppContextValue>(context);
    
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text(
            'User: ${app.user.user.name}',
            style: const TextStyle(fontSize: 20),
          ),
          Text(
            'Age: ${app.user.user.age}',
            style: const TextStyle(fontSize: 16),
          ),
        ],
      ),
    );
  }
}

/// Child component - User controls
class UserControls extends HookWidget {
  const UserControls({super.key});

  @override
  Widget build(BuildContext context) {
    final app = useContext<AppContextValue>(context);
    final nameController = useTextEditingController(app.user.user.name);
    
    return Padding(
      padding: const EdgeInsets.all(16),
      child: Column(
        children: [
          Row(
            children: [
              Expanded(
                child: TextField(
                  controller: nameController.controller,
                  decoration: const InputDecoration(labelText: 'Name'),
                ),
              ),
              const SizedBox(width: 10),
              ElevatedButton(
                onPressed: () => app.user.setName(nameController.value),
                child: const Text('Update'),
              ),
            ],
          ),
          const SizedBox(height: 10),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ElevatedButton(
                onPressed: () => app.user.setAge(app.user.user.age - 1),
                child: const Text('Age -'),
              ),
              const SizedBox(width: 20),
              ElevatedButton(
                onPressed: () => app.user.setAge(app.user.user.age + 1),
                child: const Text('Age +'),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

/// Child component - Counter control buttons
class CounterControls extends HookWidget {
  const CounterControls({super.key});

  @override
  Widget build(BuildContext context) {
    final app = useContext<AppContextValue>(context);
    
    return Center(
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          ElevatedButton(
            onPressed: app.counter.decrement,
            child: const Text('Count -'),
          ),
          const SizedBox(width: 20),
          ElevatedButton(
            onPressed: app.counter.reset,
            child: const Text('Reset'),
          ),
          const SizedBox(width: 20),
          ElevatedButton(
            onPressed: app.counter.increment,
            child: const Text('Count +'),
          ),
        ],
      ),
    );
  }
}
1
likes
150
points
160
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter package that provides React-like hooks (useState, useEffect) for state management and side effects in Flutter apps.

Repository (GitHub)
View/report issues

Topics

#hooks #state-management #react #flutter #widget

Documentation

Documentation
API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on react_hooks