Lỗi ứng dụng Flutter sau khi chuyển đổi Nhà cung cấp 3 thành 4


8

Tôi đã cố gắng nâng cấp ứng dụng Flutter của mình để sử dụng Provider 4.0.1ngày hôm nay và đoạn mã sau đã bị lỗi khi gán giá trị thành null.

Đây là mã tôi đang cố gắng chuyển đổi. Tôi chỉ thay đổi SingleChildCloneableWidgetđể SingleChildStatelessWidgetbiên dịch OK.

import 'package:provider/provider.dart';
import 'package:provider/single_child_widget.dart';

List<SingleChildStatelessWidget> providers = [
  ...independentServices,
  ...dependentServices,
  ...uiConsumableProviders
];

List<SingleChildStatelessWidget> independentServices = [
  Provider.value(value: Api()),
  Provider.value(value: Tbl()),
  Provider.value(value: Bill()),
  Provider.value(value: Sale()),
  Provider.value(value: Category()),
  Provider.value(value: Menu()),
];

List<SingleChildStatelessWidget> dependentServices = [
  ProxyProvider<Api, AuthenticationService>(
    update: (context, api, authenticationService) => AuthenticationService(api: api),
  ),
];

List<SingleChildStatelessWidget> uiConsumableProviders = [
  StreamProvider<User>(
    create: (context) => Provider.of<AuthenticationService>(context, listen: false).user,
  ),
    lazy: false
];

Tôi đã thực hiện nó như thế này:

StreamController<User> _userController = StreamController<User>();
Stream<User> get user => _userController.stream;

Sự cố xảy ra tại đường dây này:

Future<void> _setFixedLanguageStrings(BuildContext context) async {

 User _user = Provider.of<User>(context);

 _user.homeString = await translate(context, 'Home');

'Ngôn ngữ' getter được gọi là null. Người nhận: null

Điều này đã làm việc tốt với Provider 3.0.3nhưng rõ ràng tôi cần phải làm nhiều hơn nữa.

Mã ban đầu của tôi đến từ hướng dẫn này .

chỉnh sửa: Tôi đã khắc phục vấn đề đó bằng cách thêm lazy: falsevào phương thức tạo nhà cung cấp luồng nhưng sau đó lại xảy ra lỗi khác trong mã này.

Future<String> translate(BuildContext context, _term) async {

  final String _languageCode = Provider.of<User>(context).language;

mà tạo ra lỗi này:

Ngoại lệ đã xảy ra. _AssertsError ('gói: nhà cung cấp / src / nhà cung cấp.dart': Xác nhận thất bại: dòng 213 pos 7: 'bối cảnh.owner.debugBu dựng | bên ngoài cây widget.

Điều này có thể do trình xử lý sự kiện (như onPression của một nút) có tên là Carrier.of mà không vượt qua listen: false.

Để sửa, hãy viết: Carrier.of (bối cảnh, lắng nghe: sai);

Nó không được hỗ trợ vì có thể xây dựng lại widget một cách vô nghĩa với trình xử lý sự kiện, khi cây widget không quan tâm đến giá trị. )

Tôi đã thêm vào listen: falsedòng trên dường như đã khắc phục vấn đề đó, tuy nhiên nhà cung cấp tiếp theo tôi đã cố sử dụng đã tạo ra lỗi này:

Đã thử nghe một giá trị tiếp xúc với nhà cung cấp, từ bên ngoài cây widget.

Điều này có thể do trình xử lý sự kiện (như onPression của một nút) có tên là Carrier.of mà không vượt qua listen: false.

Để sửa, hãy viết: Carrier.of (bối cảnh, lắng nghe: sai);

Nó không được hỗ trợ vì có thể xây dựng lại widget một cách vô nghĩa với trình xử lý sự kiện, khi cây widget không quan tâm đến giá trị. 'gói: nhà cung cấp / src / nhà cung cấp.dart': Xác nhận thất bại: dòng 213 pos 7: 'bối cảnh.owner.debugBu dựng | | nghe == sai | | _debugIsInInheritedProviderUpdate '

Bây giờ tôi có nên đi đến mọi trường hợp mà tôi gọi cho một nhà cung cấp và thêm listen: falsekhông? Tôi cần ai đó giải thích những gì đã thay đổi và tại sao vì tôi khá mới ở Flutter và các tài liệu rất thưa thớt Provider. Có nhiều lần tôi gọi Nhà cung cấp trong mã của mình và lỗi cuối cùng này không trả về vị trí mã.

Được listen: falsehiện nay luôn luôn cần thiết khi nó không phải là trước hay tôi đã bỏ lỡ cái gì khác? Tôi đang bắt đầu thêm lắng nghe: sai cho mỗi cuộc gọi để khởi tạo biến Nhà cung cấp và nó dường như đang hoạt động nhưng đây có phải là cách tiếp cận đúng không? Tôi có nên thêm listen: falsevào mỗi cuộc gọi Provider.ofvà gọi nó một ngày không?

Lỗi chỉ ra rằng ứng dụng đã cố gắng lắng nghe một giá trị bên ngoài cây widget nhưng tôi không nghĩ đó là trường hợp như tôi gọi nó trong phương thức xây dựng widget. Nếu lỗi này là chính xác thì bằng cách nào đó tất cả các nhà cung cấp của tôi đều ở ngoài cây widget. Mã đã hoạt động tốt trong một vài tháng, các lỗi nghe chỉ xuất hiện trên bản cập nhật này.


Có cùng một vấn đề khi cập nhật. Điều đó là, nếu tôi có thể hoặc không thể thay đổi cây widget thì sao? Tôi đang quay trở lại.
Dpedrinha

Câu trả lời:


3

Tôi có cùng một "vấn đề", nếu tôi thêm listen: falseở mọi nơi tôi gọi cho Nhà cung cấp thì vấn đề không còn nữa nhưng tôi không biết đó có phải là giải pháp đúng không ...?


Tôi tự hỏi tại sao listen: falsekhông phải là mặc định cho SingleChildStatelessWidget?
markhorrocks

không có lỗi khi nghe: false, nhưng UI không cập nhật, vì vậy cần một cái gì đó khác để làm cho nó hoạt động
Shakle

1

listen : false được gọi khi dữ liệu sẽ không cập nhật bất kỳ thứ gì trong giao diện người dùng và nên được sử dụng, như xóa tất cả các thẻ trong một tiện ích khi nhấp vào nút.

Để biết thêm thông tin, hãy đọc go_to_link này


0

listen:true được mặc định là hợp lý.

Nó không chỉ định bên trong một trình xử lý sự kiện không logic.listen: false

Ngoài ra, 4.1.0 bằng cách nào đó sẽ có một sự thay thế ngắn hơn cho Carrier.of:

context.read<T>() // Provider.of<T>(context, listen: false)
context.watch<T>() // Provider.of<T>(context)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.