Flutter useEffect with Key notices value change only once

109 views Asked by At

I've written a code like below and expected the value on screen to never change from "value by useEffect".

*Since every time the button is pressed and the text is changed to "value by onPress", useEffect should catch the change and reset value to "value by useEffect".

However, the useEffect seems to have triggered only when the screen was initialized and first time the button was pressed.

From the second button press, change of text looks to be ignored by useEffect.

How does this happen?

*In other words, how to properly write a "useEffect" which reacts to change of certain property every time?

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

class PlayHooks extends HookConsumerWidget {
  PlayHooks({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final ephemeralStateText = useState("init value");

    useEffect(() {
      debugPrint("useEffect triggered.");
      ephemeralStateText.value = "value by useEffect";
      return;
    }, [ephemeralStateText.value]);

    return Scaffold(
      appBar: AppBar(title: Text("play hooks")),
      body: Center(
        child: Column(children: [
          Text("ephemeral state text is ${ephemeralStateText.value}"),
          ElevatedButton(
              onPressed: () => ephemeralStateText.value = "value by onPress",
              child: Text("change ephemeral state text")),
        ]),
      ),
    );
  }
}
1

There are 1 answers

4
Dhafin Rayhan On BEST ANSWER

You don't need to use curly braces on function shorthand in Dart. The syntax => expr is equal to { return expr; }. Otherwise, the function will return whatever defined by the expression with curly braces (like Map or Set). Notice how this is different with Javascript arrow function syntax.

Change this:

onPressed: () => {ephemeralStateText.value = "value by onPress"}

to this:

onPressed: () => ephemeralStateText.value = "value by onPress"

More about function syntax in Dart: https://dart.dev/language/functions


UPDATE:

As mentioned by the OP, final solution is to remove this line from the callback inside useEffect:

ephemeralStateText.value = "value by useEffect";