본문 바로가기
Flutter

[Flutter] 플러터 - RiverPod 상태관리(3) StateProvider 여러 값 사용해 보기

by s_hoonee 2024. 1. 30.
반응형

Provider, StateProvider, StateNotifierProvider  사용 예시로 이루어진 시리즈

기존 포스팅 시리즈 3탄입니다. 아래 게시물을 먼저 확인해 주세요.
https://hooninha.tistory.com/87

 

[Flutter] 플러터 - RiverPod 상태관리(2) StateProvider 단일 값 사용해 보기

기존 포스팅 시리즈 2탄입니다. 아래 게시물을 먼저 확인해 주세요. https://hooninha.tistory.com/81 [Flutter] 플러터 - RiverPod 상태관리 사용해 보기(1) Provider Provider flutter_riverpod Provider, StateProvider, StateNotif

hooninha.tistory.com

이번 포스팅에는 StateProvider를 사용하여 관리하고자 하는 필드들을 클래스로 묶어 상태를 관리하는 예시를 보여드리겠습니다.

 

실습에 필요한 파일은 두개입니다!

 

1. StateProvider 생성 - 클래스  활용하기

지난 시간에는 단일 값으로 StateProvider을 사용했었죠? 아래는 단일 값을 관리한 이전 포스팅 예제입니다.  

final userNameProvider = StateProvider((ref) => "hoony");

이번엔 다중 값을 넣기 위해 우리가 관리하고자 하는 멤버들을 클래스로 묶어 넣어주고 초기화해줍니다.

states.dart 파일에 해당 코드를 작성해줍니다. 

import 'package:flutter_riverpod/flutter_riverpod.dart';

class MyObject {
  final String stringValue;
  final int intValue;

  MyObject({required this.stringValue, required this.intValue});
}

final myObjectProvider = StateProvider<MyObject>((ref) {
  return MyObject(stringValue: '초기값', intValue: 0);
});

이렇게 하면 myObjectProvider는 MyObject 타입의 객체를 가지게 됩니다. 이 객체 안에 stringValue와 intValue 두 가지 값을 저장하고, 필요에 따라 값을 업데이트할 수 있습니다.

 

2. 생성한 StateProvider 사용하기

Myobject 멤버인 stringValue와 intValue를 읽고 쓰는 예제입니다.

read_state_provider.dart 파일에 해당 코드를 작성해줍니다.

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:gym_app/page/riverpod_page/stateProvider/state.dart';
import 'package:gym_app/page/riverpod_page/stateProviders/states.dart';

class ReadStateProviders extends ConsumerWidget {
  const ReadStateProviders({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('StateProviders'),
      ),
      body: Center(
        child: Column(
          children: [
            Text(
              ref.watch(myObjectProvider).stringValue,
              style: const TextStyle(
                  fontSize: 30, fontWeight: FontWeight.bold, color: Colors.red),
            ),
            Text(
              ref.watch(myObjectProvider).intValue.toString(),
              style: const TextStyle(
                  fontSize: 30, fontWeight: FontWeight.bold, color: Colors.red),
            ),
            ElevatedButton(
              onPressed: () {
                ref.read(myObjectProvider.notifier).state =
                    MyObject(stringValue: '스트링값', intValue: 1234);
              },
              child: const Text('스트링값과 인트값 변경'),
            ),
            ElevatedButton(
              onPressed: () {
                ref.refresh(myObjectProvider);
              },
              child: const Text('초기값으로 변경'),
            ),
          ],
        ),
      ),
    );
  }
}

ref.watch(myObjectProvider)에 접근하니 관리하고자 하였던 클래스의 멤버들에 접근할 수 있었습니다. 

관리하고자 하는 모델의 각 필드에 접근하는 모습입니다. watch 함수로 하여금 값이 변경될 때 재렌더링 되도록 합니다.

 

우리가 등록해놓은 값으로 상태의 값을 변경하는 부분입니다. 사용자한테 입력 받은 값이나 생성자로 넘어온 값 등을 넘겨주어 로직을 짜면 됩니다. 다음 시간엔 상태관리 값들을 copyWith형태로 관리하여 변경하는 로직에 대해 포스팅 하겠습니다.