英文:
Getting error when trying to add WidgetRef parameter to the build method in Flutter
问题
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(
const ProviderScope(
child: MyApp(),
),
);
}
class MyApp extends HookWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
Future<DocumentSnapshot<Map<String, dynamic>>> getUserData(userId) async {
final userData = await FirebaseFirestore.instance
.collection('users')
.doc(userId)
.get();
return userData;
}
final ref = useProvider(currentUserProvider.notifier);
useEffect(() {
if (FirebaseAuth.instance.currentUser != null) {
final currentUserId = FirebaseAuth.instance.currentUser!.uid;
getUserData(currentUserId).then((currentUserData) {
var currentUser = CurrentUser(
uid: currentUserId,
mobile: currentUserData.data()!['mobile'],
// some more fields
);
ref.updateCurrentUser(currentUser);
});
}
return null;
}, []);
return MaterialApp(
title: 'MyTitle',
home: StreamBuilder(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (ctx, snapshot) {
if (snapshot.hasData) {
return const TabsScreen();
}
return const SignInScreen();
},
),
);
}
}
请注意,我已经更新了代码中的一些问题。现在,ref
变量已经在 useProvider
中正确获取,以便在 useEffect
中使用。此外,我还修复了构造函数的错误签名。
英文:
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(
const ProviderScope(
child: MyApp(),
),
);
}
class MyApp extends HookWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
Future<DocumentSnapshot<Map<String, dynamic>>> getUserData(userId) async {
final userData = await FirebaseFirestore.instance
.collection('users')
.doc(userId)
.get();
return userData;
}
useEffect(() {
if (FirebaseAuth.instance.currentUser != null) {
final currentUserId = FirebaseAuth.instance.currentUser!.uid;
getUserData(currentUserId).then((currentUserData) {
var currentUser = CurrentUser(
uid: currentUserId,
mobile: currentUserData.data()!['mobile'],
// some more fields
);
ref.read(currentUserProvider.notifier).updateCurrentUser(currentUser);
});
}
return null;
}, []);
return MaterialApp(
title: 'MyTitle',
home: StreamBuilder(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (ctx, snapshot) {
if (snapshot.hasData) {
return const TabsScreen();
}
return const SignInScreen();
},
),
);
}
}
This is the code I have in my main.dart file. I am trying to set a state in Riverpod every time the app launches. I am using useEffect Flutter hook to achieve the same. But to set the state, I need to get ref
. When I try to add a parameter WidgetRef ref
to the build
function, I get the following error -
'MyApp.build' ('Widget Function(BuildContext, WidgetRef)') isn't a valid override of 'StatelessWidget.build' ('Widget Function(BuildContext)').
I don't know if there is some syntax error, or if the MainApp widget should (somehow) be converted to statefulWidget, or I need to take a totally different approach to achieve what I need?
P.S.: I am importing all the required files. Just not pasted that code here.
答案1
得分: 0
事实上,如上所述,您需要使用 HookConsumerWidget
而不是 HookWidget
,以便在 build
方法中访问 ref
:
class MyApp extends HookConsumerWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {...}
}
您还可以使用 HookConsumer
来子树化小部件:
HookConsumer(builder: (context, ref, child) {
return Text(ref.watch(provider));
},);
英文:
Actually, as noted above, you need to use HookConsumerWidget
instead of HookWidget
so that you have access to ref
in the build
method:
class MyApp extends HookConsumerWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {...}
You can also use HookConsumer
to subtree the widget:
HookConsumer(builder: (context, ref, child) {
return Text(ref.watch(provider));
},);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论