본문 바로가기

코딩강의/favorite_places(플러터-유데미)

~238. Adding Places with Provider & Displaying Places (Challenge Solution 5/6)

1. 리버팟 provider를 사용해서 값을 전역에 사용해보자.

flutter pub add flutter_riverpod 설치

 

- providers/user_places.dart

import 'package:flutter_riverpod/flutter_riverpod.dart';

import 'package:favorite_places/models/place.dart';

class UserPlacesNotifier extends StateNotifier<List<Place>> {
  UserPlacesNotifier() : super(const []);

  void addPlace(String title) {
    final newPlace = Place(title: title);
    state = [newPlace, ...state];
  }
}

final userPlacesProvider =
    StateNotifierProvider<UserPlacesNotifier, List<Place>>(
  (ref) => UserPlacesNotifier(),
);

 

1) 이전 다른프로젝트에서 사용했던 사용법과 같다.

2)  StateNotifierProvider<UserPlacesNotifier, List<Place>> ~~ --> 지정해주어야 함.

3) title값을 받고, state 리스트값에 넣어준다.

 

- main.dart

https://github.com/academind/flutter-complete-guide-course-resources/blob/main/Code%20Snapshots/13%20Native%20Device%20Features/04%20Added%20riverpod/lib/main.dart

 

1)void main() {
  runApp(
    const ProviderScope(child: MyApp()),
  );
}

 

--> MyApp을 ProviderScope로 감싸준다.

 

- add_place.dart

https://github.com/academind/flutter-complete-guide-course-resources/blob/main/Code%20Snapshots/13%20Native%20Device%20Features/04%20Added%20riverpod/lib/screens/add_place.dart

 

1) stateful이기 때문에 ConsumerStatefulWidget으로 교체,  밑에는 ConsumerState로 교체

2)   void _savePlace() {
    final enteredTitle = _titleController.text;

    if (enteredTitle.isEmpty) {
      return;
    }

    ref.read(userPlacesProvider.notifier).addPlace(enteredTitle);

    Navigator.of(context).pop();
  }

--> 텍스트 필드에서 값을 저장할 때 쓰이는 함수, 간단한 유효성 검사를 진행하고, ref를 통해 리버팟 provider와 연결한다. addPlace를 통해 인자를 넘겨준다. 그리고 pop을 통해 뒤로가기.

 

- places.dart

https://github.com/academind/flutter-complete-guide-course-resources/blob/main/Code%20Snapshots/13%20Native%20Device%20Features/04%20Added%20riverpod/lib/screens/places.dart

 

1) 위에서 리버팟에 값을 저장했다면, 여기서는 리버팟에서 값을 가져온다.

2) stateless 화면이라 ConsumerWidget 로 대체

3)   Widget build(BuildContext context, WidgetRef ref) {
    final userPlaces = ref.watch(userPlacesProvider);

    return Scaffold(
      appBar: AppBar(
        title: const Text('Your Places'),
        actions: [
          IconButton(
            icon: const Icon(Icons.add),
            onPressed: () {
              Navigator.of(context).push(
                MaterialPageRoute(
                  builder: (ctx) => const AddPlaceScreen(),
                ),
              );
            },
          ),
        ],
      ),
      body: PlacesList(
        places: userPlaces,
      ),
    );
  }
}

--> 빌드 인자에 ref를 추가해주고, ref.watch를 통해 리버팟 state값을 가져온다. 그리고 그 값을 userPlaces에 담고, body값에 전달해준다.