인프런 커뮤니티 질문&답변

etax님의 프로필 이미지
etax

작성한 질문수

[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!

riverpod 상태관리시에 궁금한점 질문드립니다.

작성

·

338

·

수정됨

0

안녕하세요 코팩님.

상품검색 페이지를 작업했습니다.

riverpod으로 상태관리를 하며 필터(검색조건)을 provider로 구현하였습니다.

필터들은 stateProvider로 하였고

검색데이터 list는 StateNotifierProvider(필터값들 watch중)로 선언하였습니다.

기본적으로 필터가 변경될때 자동으로 재검색이 되고 있는데요.

 

검색결과 페이지에서 새로운 검색어를 넣고 다시 검색할 때 이슈가 있습니다.

(pushReplacementNamed로 현재페이지를 다시 호출)

사정상 검색어는 provider로 하지 않고 파라미터로 받고 있습니다.

 

필터프로바이더들을 초기화 하지 않으면 새로운검색결과에 조건이 또 타게되서 필터들을 초기화 해주고 싶은데요.

필터를 초기화해주면 기존 리스트가 자동으로 watch중이라 재검색이 먼저 실행되어버립니다.

invalidate도 마찬가지구요.

 

어쩔수없이 changeNotifierProvider를 써서 notifyListeners를 호출하지 않고 값을 변경하는 함수를 따로 만들어서 그걸 호출 해서 값을 초기화하고 pushReplacementNamed로 현재페이지를 검색어만 바꿔서 재호출 하는걸로 처리하고 넘어갔습니다.

 

이럴땐 어떻게 처리해야 할까요?

기본적인 설계를 잘못한 건지 모르겠습니다 ㅠㅠ

조언 부탁드립니다.

 

ps. autoDispose를 걸어놔도 다음 페이지에서 해당 프로바이더를 사용하면 dispose가 되지 않고 상태값도 초기화없이 유지되는게 맞나요? 테스트해 보았는데 그렇게 처리되는 것처럼 보여서요.

 

긴글 읽어주셔사 감사합니다.

 

 

 

답변 1

0

코드팩토리님의 프로필 이미지
코드팩토리
지식공유자

안녕하세요!

필터를 초기화 (아무 값이 없는 스트링 -> "")이 되면 검색이 실행 안되도록 하고싶다는 말씀 맞을까요?

그렇다면 검색을 실행하는 함수에서 스트링 길이가 0이면 함수를 실행하지 않도록 조건을 넣으면 안되나요?

아무래도 제가 질문을 잘못 이해한 것 같긴 한데 예제와 함께 질문 부탁드립니다.

감사합니다!

etax님의 프로필 이미지
etax
질문자

안녕하세요~! 답변 감사합니다.

 

step1. 검색어 [패딩]으로 상품검색

step2. [패딩]검색결과에서 색상필터를 {빨강} 으로 변경 => 변경과동시에 자동으로 [패딩]+{빨강} 조건으로 검색결과 갱신

step3.{빨강}조건을 다시 없앨경우 => 기본 [패딩]검색결과로 자동갱신

step4.{검정}조건을 추가시 => 다시 [패딩]+{검정}조건으로 자동갱신

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ이슈ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

step5.현재 화면에서 검색어를 [바지]로 변경하여 현재 페이지 재호출

step6.필터인{검정}은 autoDispose지만, 현재페이지를 pushReplacementNamed로 호출하니 dispose되지않고 유지되고 결과는 [바지]+{검정} 조건으로 조회됨

 

말씀해주신 필터값이 없을때 조회를 하지 않게되면

step3번에서 자동갱신이되지 않습니다.

 

말씀해주신 부분에서 힌트를 얻어 값이 없으면 갱신하지 않게 하고,

단순히 검색조건이 빠지는 케이스는 조회를 새로하는 메소드를 stateNotifierProvider에 만들어서 호출하도록 만들면 될 것 같다는 생각이 들긴 합니다!

 

하지만 뭔가 제가 잘못해서 번거롭게 돌아가는 거 같다는 생각이 들어서요.

프로그래밍적으로 watch되어지고 있는 프로바이더들의 값이 변경될때

notifyListeners()효과를 안주는 방법이 있을까요??

 

기존 프로젝트에서는 riverpod이 아닌 기본 provider를 썼고, changeNotifierProvider를써서

필요한 부분에서만 notifyListeners()를 써줘서 이번과 같은 이슈는 없었습니다.

 

소스코드없이 제가 설명을 잘 못해서 죄송합니다.

지금은 제가 이미 changeNotifierProvider로 변경해서 처리한 마지막 소스만 가지고있어서 코드는 따로 올리지 않았습니다.

 

감사합니다~!

 

 

 

 

 

코드팩토리님의 프로필 이미지
코드팩토리
지식공유자

안녕하세요!

무슨 문제인지 이제는 이해가 조금 되는 것 같습니다.

사실 문제를 정확히 이해하고 계시기 때문에 응급처치법은 쉽습니다.

pushReplacementNamed를 실행할 경우 또는 검색어를 변경할 경우 필터를 empty로 변경해주시면 됩니다.

제 생각엔 검색어가 변경될때 실행해주는게 가장 좋을 것 같네요.

만약에 이 방법이 마음에 들지 않는다면 어떤 방향으로 작업 하고싶으신지 조금 더 알려주셔야 할 것 같습니다.

그리고 제가 이해한게 맞다면 step3에서 필터 없앨때도 '검색' 프로바이더에서 검색을 다시 실행주시면 될 것 같습니다.

감사합니다!

etax님의 프로필 이미지
etax
질문자

추가 답변 감사합니다~!

empty 처리를 해줘야 한다는 부분이 ''값과 같은 값으로 업데이트 하라는 말씀일까요?

아니면 제가 모르는 empty 메소드같은것(notifier가 되지 않고 비우는)이 있을까요?

 

chanageNotifier를 쓰기 전에는 저도

필터가 변경될때 공백으로 업데이트를 해주고

대신 검색결과를 조회하는 메소드에서 자동으로 필터변경을 감지하고 재조회할때

flag변수를 둬서 재조회 하지 않도록 변경해서 처리를 하긴 했습니다~

개발자가 업무적으로 flag를 두는 방법도 당연히 많이 쓰는 방법이겠지만,

사실 심플하게 changeNotifier 에서의 notifyListeners와 같이 잠시 변경알림을 하지 않는 방법이 있는지 하는게 가장 궁금했습니다~

이게 riverpod의 철학과 맞지 않는 부분인건지, 있을법하다고 느껴저서요~

실제 처리는 고집을 부려서 chanageNotifier로 해서 선택적으로 notifier를 하는방법으로 하긴 했습니다 ㅎ

 

감사합니다~!

 

 

 

 

코드팩토리님의 프로필 이미지
코드팩토리
지식공유자

StateNotifer에서 바라보고있는 상태를 변경하지만 화면에 반영되지 않게 하는게 오히려 안티 패턴입니다. 말씀하신대로 조건문으로 처리하시는게 제일 '편한' 방법일 것 같아요.

etax님의 프로필 이미지
etax

작성한 질문수

질문하기