flutter redux의 distinct에서 다시 그리기 방지

11316 단어 DartreduxFlutter

소개



flutter_redux의 도입을 고려하고 있기 때문에,
신경이 쓰이는 곳을 조사해 보았습니다.

Redux 자체에 관해서는 다른 좋은 기사가 많이있을 것이라고 생각하기 때문에,
그쪽을 참고해 주시면 좋겠습니다.

궁금한 점



flutter_redux에서는, 신경쓰지 않고 사용해 버리면 State가 변경될 때마다, 같은 값이었다고 해도
StoreConnector 다음은 모두 다시 그려져 버렸습니다.

그럼 어떻게 할까



이를 방지하기 위해 flutter_redux에서는
StoreConnector에 distinct라는 인수가 제공되는 것 같습니다.
//ライブラリの該当部
    if (widget.distinct) {
      stream = stream.where((vm) {
        final isDistinct = vm != latestValue;

        return isDistinct;
      });
    }

distinct가 true이면 가장 최근 값과 현재 값을 비교하고,
같은 값이면 현재 값이 필터링되는 것 같습니다.

카운터 앱



실제로 만들어보고 확인해 보겠습니다.
표시부는 참조하는 State는 동일하고, 2개의 StoreConnector를 사용해,
ViewModel로 변환하고 있습니다.

아래는 상부 카운터의 표시부
class IntText extends StatefulWidget {
  @override
  _IntTextState createState() => _IntTextState();
}

class _IntTextState extends State<IntText> {
  @override
  Widget build(BuildContext context) {
    return StoreConnector<AppState, IntViewModel>(
      distinct: true,
      converter: (store) => IntViewModel(state: store.state),
      builder: (context, viewModel) {
        print('int rebuild');
        return Text(
          viewModel.intCount,
          style: Theme.of(context).textTheme.display1,
        );
      },
    );
  }
}




distinct를 사용하려면



ViewModel 등으로 Object를 비교하는 메소드를 Override 할 필요가 있습니다.
아래와 같이 ==와 hashCode를 Override합니다.
@immutable
class AppState {
  final int intCount;
  final double doubleCount;

  const AppState({
    this.intCount = 0,
    this.doubleCount = 0.0,
  });

  AppState copyWith({
    int intCount,
    double doubleCount,
  }) {
    return AppState(
      intCount: intCount ?? this.intCount,
      doubleCount: doubleCount ?? this.doubleCount,
    );
  }
}


class IntViewModel {
  final String intCount;

  IntViewModel({
    AppState state,
  }) : intCount = state.intCount.toString();

  @override
  int get hashCode => intCount.hashCode;

  @override
  bool operator ==(Object other) {
    //identicalは参照を比較する。
    return identical(this, other) ||
        other is IntViewModel &&
            runtimeType == other.runtimeType &&
            intCount == other.intCount;
  }
}
class DoubleViewModel {
  final String doubleCount;

  DoubleViewModel({
    AppState state,
  }) : this.doubleCount = state.doubleCount.toString();

  @override
  int get hashCode => doubleCount.hashCode;

  @override
  bool operator ==(dynamic other) {
    return identical(this, other) ||
        other is DoubleViewModel &&
            runtimeType == other.runtimeType &&
            doubleCount == other.doubleCount;
  }
}

비교



distinct:false



distinct가 False인 경우,
텍스트가 두 가지 모두 업데이트되었습니다.
이번 예에서는 다시 그리는 Widget이 적기 때문에,
문제가 되지 않는다고 생각하지만 많아지면
성능면에서 문제가 되는 것이 아닐까요?



distinct:true



그런 다음 distinct가 True의 예입니다.
변경된 TextWidget만 변경되었음을 확인할 수 있습니다.



리포지토리는 여기

요약



Object 비교용의 메소드의 보일러 플레이트의 양은 증가해 갈 것 같은 곳은 우려점입니다만,
어느 정도 최적화할 수 있었을까요?

단지 우려점의 부분에 대해서는, Equatable 라고 하는 라이브러리가 있는 것 같기 때문에,
시도하고 싶습니다.

틀린 곳 등 있으면 지적해 주시면 감사하겠습니다.

좋은 웹페이지 즐겨찾기