带有参数的Riverpod提供商

时间:2020-08-05 07:26:09

标签: flutter dart provider state-management

我想将我的整个项目从提供者转移到Riverpod。但我现在被困住了。

class EditQuestionScreen extends StatelessWidget {
  EditQuestionScreen({this.question, this.answers});

  final QuestionModel question;
  final List<AnswerModel> answers;

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
        create: (context) => QuestionProvider(
            question: this.question,
            answers: this.answers),
        child: Container());
  }
}

这是我的子小部件的提供程序小部件。它仅初始化一次。如何使用Riverpod将此类移至Hook Widget?

1 个答案:

答案 0 :(得分:2)

快速笔记-使用Provider或Riverpod,您实际上并不想/不需要命名您要提供的事情thingProvider。您不是在提供提供者,而是在提供有意义的东西。

我尽力填补了您未提供的其余代码的空白,因此希望这会有所帮助:

class QuestionModel {
  QuestionModel(this.id);

  final int id;
}

class AnswerModel {
  AnswerModel(this.id);

  final int id;
}

class QuestionWithAnswers {
  QuestionWithAnswers(this.question, this.answers);

  final QuestionModel question;
  final List<AnswerModel> answers;
}

class QuestionAnswerNotifier extends ChangeNotifier {
  QuestionAnswerNotifier(this.qwa);

  final QuestionWithAnswers qwa;

  QuestionModel get question => qwa.question;
  List<AnswerModel> get answers => qwa.answers;

  addAnswer(AnswerModel answer) {
    qwa.answers.add(answer);
    notifyListeners();
  }
}

final questionProvider =
    ChangeNotifierProvider.family<QuestionAnswerNotifier, QuestionWithAnswers>(
        (ref, qwa) => QuestionAnswerNotifier(qwa));

class EditQuestionScreen extends HookWidget {
  EditQuestionScreen({
    @required QuestionModel question,
    @required List<AnswerModel> answers,
    Key key,
  })  : qwa = QuestionWithAnswers(question, answers),
        super(key: key);

  final QuestionWithAnswers qwa;

  @override
  Widget build(BuildContext context) {
    final provider = useProvider(questionProvider(qwa));

    // Use data from provider to render your UI, for example:
    return Container(
      child: Column(
        children: <Widget>[
          Text('${provider.question}\n${provider.answers}'),
          RaisedButton(
            onPressed: () => provider.addAnswer(AnswerModel(5)),
            child: Icon(Icons.add),
          )
        ],
      ),
    );
  }
}

这里要注意几件事。

  1. 在Riverpod中,家庭是我们将参数传递给提供程序的方式。
  2. QuestionWithAnswers类通过 family 提供的额外参数将要传递给提供者的模型捆绑在一起。
  3. 提供者的名称后缀有Provider,而不是提供者所提供的名称。
  4. 我们正在提供ChangeNotifier,因此称为useProvider时将返回该内容。