본문 바로가기
Flutter/Flutter FAQ

Flutter 플러터 - setState가 내부 Stateful 위젯을 업데이트하지 않습니다., Flutter - setState not updating inner Stateful Widget

by 베타코드 2023. 9. 26.
반응형

질문


기본적으로 나는 웹 사이트에서 정보를 가져오는 비동기 함수로 내용이 업데이트되는 앱을 만들려고 하고 있습니다. 그러나 새로운 상태를 설정하려고 할 때 새로운 내용을 다시 로드하지 않습니다. 앱을 디버그하면 현재 내용이 새로운 것임을 보여주지만 "재구성" 후에는 새로운 정보가 표시되지 않습니다.

편집: loadData() 메서드는 기본적으로 http 패키지로 URL을 읽어옵니다. URL에는 내용이 5분마다 변경되는 새로운 뉴스가 포함된 JSON 파일이 있습니다. 예를 들어 항상 변하는 스포츠 실시간 스코어 보드의 .json 파일로, 내용은 항상 새로운 결과와 함께 변경되어야 합니다.

class mainWidget extends StatefulWidget
{    
  State<StatefulWidget> createState() => new mainWidgetState();
}

class mainWidgetState extends State<mainWidget>
{

  List<Widget> _data;
  Timer timer;

  Widget build(BuildContext context) {
     return new ListView(
              children: _data);
  }

  @override
  void initState() {
    super.initState();
    timer = new Timer.periodic(new Duration(seconds: 2), (Timer timer) async {
      String s = await loadData();
      this.setState(() {
        _data = <Widget> [new childWidget(s)];
      });
      });
  }
}

class childWidget extends StatefulWidget {
  childWidget(String s){
    _title = s;
  }

  Widget _title;

  createState() => new childState();
}

class childState extends State<gameCardS> {

  Widget _title;

  @override
  Widget build(BuildContext context) {
    return new GestureDetector(onTap: foo(),
       child: new Card(child: new Text(_title));

  }

  initState()
  {
    super.initState();
    _title = widget._title;
  }
}

답변


이것은 당신의 문제를 해결해줄 것입니다. 기본적으로 항상 build 메소드 계층 구조에서 위젯을 생성하고 싶습니다.

import 'dart:async';

import 'package:flutter/material.dart';

void main() => runApp(new MaterialApp(home: new Scaffold(body: new MainWidget())));

class MainWidget extends StatefulWidget {
    @override
    State createState() => new MainWidgetState();
}

class MainWidgetState extends State<MainWidget> {

    List<ItemData> _data = new List();
    Timer timer;

    Widget build(BuildContext context) {
        return new ListView(children: _data.map((item) => new ChildWidget(item)).toList());
    }

    @override
    void initState() {
        super.initState();
        timer = new Timer.periodic(new Duration(seconds: 2), (Timer timer) async {
            ItemData data = await loadData();
            this.setState(() {
                _data = <ItemData>[data];
            });
        });
    }


    @override
    void dispose() {
        super.dispose();
        timer.cancel();
    }

    static int testCount = 0;

    Future<ItemData> loadData() async {
        testCount++;
        return new ItemData("테스트 #$testCount");
    }
}

class ChildWidget extends StatefulWidget {

    ItemData _data;

    ChildWidget(ItemData data) {
        _data = data;
    }

    @override
    State<ChildWidget> createState() => new ChildState();
}

class ChildState extends State<ChildWidget> {

    @override
    Widget build(BuildContext context) {
        return new GestureDetector(onTap: () => foo(),
            child: new Padding(
                padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 24.0),
                child: new Card(
                    child: new Container(
                        padding: const EdgeInsets.all(8.0),
                        child: new Text(widget._data.title),
                    ),
                ),
            )
        );
    }

    foo() {
        print("카드 탭됨: " + widget._data.toString());
    }
}

class ItemData {
    final String title;

    ItemData(this.title);

    @override
    String toString() {
        return 'ItemData{title: $title}';
    }
}
반응형

댓글