首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在颤动中卸载元件(相当于React componentWillUnmount) -颤动腹板

在颤动中卸载元件(相当于React componentWillUnmount) -颤动腹板
EN

Stack Overflow用户
提问于 2020-12-05 03:39:44
回答 2查看 1K关注 0票数 0

我有小工具,是在页面更改卸载。

我使用的是flutter web。

我看了所有的方法here,但我似乎找不到一个。

我试过了

代码语言:javascript
运行
复制
@override
void dispose() {
  print("dispose?"); 
  super.dispose();   
}

@override
void deactivate() {
  print("deactivate");
  super.deactivate();
}

这两个都没有被调用。

这是一件非常简单的事情,我需要检测小部件何时没有被“构建”(呈现)。我不认为有一些东西来保护页面更改是解决方案,它似乎有点过头了。谢谢

添加代码示例

代码语言:javascript
运行
复制
import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: 'Named Routes Demo',
    initialRoute: '/',
    routes: {
      '/': (context) => FirstScreen(),
      '/second': (context) => SecondScreen(),
    },
  ));
}

class FirstScreen extends StatefulWidget {
  FirstScreen({Key key}) : super(key: key);

  @override
  _FirstScreenState createState() => _FirstScreenState();
}

class _FirstScreenState extends State<FirstScreen> {
  @override
void dispose() {
  print("dispose"); 
  super.dispose();   
}

@override
void deactivate() {
  print("deactivate");
  super.deactivate();
}
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First Screen'),
      ),
      body: Center(
        child: ElevatedButton(
          child: Text('Launch screen'),
          onPressed: () {
            Navigator.pushNamed(context, '/second');
          },
        ),
      ),
    );
  }
}

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Second Screen"),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            // Navigate back to the first screen by popping the current route
            // off the stack.
            Navigator.pop(context);
          },
          child: Text('Go back!'),
        ),
      ),
    );
  }
}

当导航到第二个屏幕时,似乎既没有调用deactive,也没有调用dispose,并且第一个屏幕小部件不再是呈现树的一部分。那么该调用什么来检测屏幕1离开呈现树呢?

EN

回答 2

Stack Overflow用户

发布于 2020-12-07 18:36:04

如果Widget尚未挂载,则返回它。但您必须在任何setState方法之前执行此操作

代码语言:javascript
运行
复制
if (!mounted) return;
setState(() {});

代码语言:javascript
运行
复制
if (mounted) {
   //your code
};
setState(() {});

你可以在这里阅读更多信息:https://api.flutter.dev/flutter/widgets/State/mounted.html

无论如何,在构建之前唯一被调用的就是initState。您在其中所做的一切都在build之前。初始化状态:https://api.flutter.dev/flutter/widgets/EditableTextState/initState.html

票数 0
EN

Stack Overflow用户

发布于 2020-12-16 01:23:48

在您添加的代码示例中,screen 1永远不会卸载,因此不会触发这些回调。屏幕2渲染在屏幕1的顶部,并且两个屏幕都已挂载。

您可以通过在屏幕1的状态中添加一个定期回调,add让它打印出它是否仍然被挂载,来确认屏幕1始终处于挂载状态,例如:

代码语言:javascript
运行
复制
  import 'dart:async';
  
  // in _FirstScreenState, add:

  @override
  void initState() {
    Timer.periodic(Duration(seconds: 1), (timer) {
      print("screen 1 is still mounted? $mounted");
    });
    super.initState();
  }

你会看到,它总是被挂载的,即使屏幕2渲染在屏幕1的顶部。

此外,您可以对screen 2执行相同的deactivatedispose逻辑,您将看到,当从screen 2导航回到screen 1时,screen 2是真正卸载的,并且这两个回调都正常工作。因此,再次证明问题不在于这些回调,而在于screen 1没有卸载。

所以没错..。在您发布代码示例之前,我认为您遇到了一些关于小部件被卸载(已失效)的错误。但在这种情况下,由于您使用的是按钮,因此确切地知道页面转换发生的时间,也许您可以在按钮回调中做您需要做的任何业务逻辑?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65149714

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档