-
-
Notifications
You must be signed in to change notification settings - Fork 189
-
I have a text controller where with each key entry, I'm updating an image, hence a rebuild. I've tried a number of ways to refocus back on the text box after the rebuild from useEffect(), and while visually the focus of the text box shows, I can't actually type anything unless I click on the text box (backspace works for some reason). I'm not sure why, my understanding of the rebuild process is lacking but can't seem to get an explanation.
Tried various different adjustments in useEffect(), also would like to avoid using autofocus parameter in the text box widget (whose code I also tried to use as a reference). All the solutions I've tried, however, work fine if I stop using flutter hooks and use setState().
In the example code provided, because it's a lot more basic, I have also worked around this in this example by not using useState('') and using useListener() and wrapping the text box widget with a focus widget (doesn't work with useState), but would like to solve this using useState() as I need it for my implementation.
import 'package:fluent_ui/fluent_ui.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return FluentApp(
title: 'Flutter Demo',
theme: FluentThemeData(accentColor : Colors.blue,),
home: HomePage(),
);
}
}
class HomePage extends HookWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final urlTextController = useTextEditingController();
final urlTextNotif = useState('');
final selectedIndexState = useState(0); //edit
final selectedIndex = selectedIndexState.value; //edit
final focusNode = useFocusNode();
useEffect(() {
focusNode.requestFocus();
urlTextController.addListener(() {
urlTextNotif.value = urlTextController.text;
});
return () {
urlTextController.dispose();
};
}, [focusNode, urlTextController]);
return NavigationView(
pane: NavigationPane(
items: [
PaneItem(
title: const Text('test'),
body: Column(
children: [
TextBox(
controller: urlTextController,
focusNode: focusNode,
),
Text('Typed text: ${urlTextNotif.value}'),
],
),
icon: const Icon(FluentIcons.to_do_logo_outline),
),
],
selected: selectedIndex,
onChanged: (index) {selectedIndexState.value = index;},
),
);
}
}
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 2 comments 6 replies
-
int selectedIndex = 0;
You cannot store state as properties of your widgets like this.
Beta Was this translation helpful? Give feedback.
All reactions
-
Apologies, when I was splicing the code to keep it shorter, I didn't catch that.
I can get it to work if I force focusNode() to be rebuilt by adding a HookBuilder -> useEffect -> focusNode.requestFocus() inside of Column(). Not sure why the above implementation of useEffect() doesn't work.
Beta Was this translation helpful? Give feedback.
All reactions
-
Thank you for bug fixes regarding widget focus, this code now works without any changes.
Beta Was this translation helpful? Give feedback.
All reactions
-
@anfernydc what was the fix for you? I think I'm running into a similar issue. Here's my snippet. I have a widget to edit definition
, but when a value is fetched from workoutProvider
it should replace the definition with the fetched value and rebuild
final fetchedWorkout = ref.watch(workoutProvider); // returns AsyncValue<WorkoutDefinition> final definition = useState(null as WorkoutDefinition?); useEffect(() { fetchedWorkout.when( data: (data) => definition.value = data, // <-- this is being hit correctly but the widget is not rebuilt error: (error, stackTrace) { /* show error */ }, loading: () => definition.value = null, ); return null; }, [fetchedWorkout]);
Beta Was this translation helpful? Give feedback.
All reactions
-
Actually after re-reading, it sounds like your update of the value notifier was re-building correctly, so this isn't the same issue
Beta Was this translation helpful? Give feedback.
All reactions
-
My first guess was that the captured definition
value provider in the when -> data
callback is stale, although its hashcode matches the hashcode from the first build and when it rebuilds after workoutProvider
updates.
@rrousselGit am I doing something wrong here?
Beta Was this translation helpful? Give feedback.
All reactions
-
Found my issue, I needed to wrap my update in a Future.microtask
as described here #153
And I ended up refactoring to do the update prior to the build as suggested in the comments
Beta Was this translation helpful? Give feedback.
All reactions
-
Sorry just saw your comment in my email now, good to hear you worked it out! I might end up running into a similar issue so I'm thankful you mentioned how you got it to work. At the time I also ran into focusNode and useEffect having some conflicts, left that alone, and one day after Flutter/hooks was updated, it just worked.
Beta Was this translation helpful? Give feedback.