Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

onTransitionend在百度小程序部分场景下不会触发且组件更新异常 #8987

Closed
yuzhounanhai opened this issue Mar 30, 2021 · 5 comments · Fixed by #9197
Closed
Labels
F-react Framework - React T-swan Target - 编译到百度小程序 V-3 Version - 3.x
Milestone

Comments

@yuzhounanhai
Copy link

yuzhounanhai commented Mar 30, 2021

相关平台

百度小程序

小程序基础库: 3.280.26
使用框架: React

复现步骤

基础组件:fade进入后停留2s后fade退出

import { View } from '@tarojs/components';
import React from 'react';

export default class Comp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      show: false,
    }
  }

  componentDidMount() {
    setTimeout(() => {
      this.setState({
        show: true,
      });
    }, 1000);
  }

  handleOnTransitionend = () => {
    if (this.state.show) {
      setTimeout(() => {
        this.setState({
          show: false,
        });
      }, 2000);
    } else {
      typeof this.props.onHide === 'function' && this.props.onHide();
    }
  }

  render() {
    return (
      <View
        onTransitionEnd={this.handleOnTransitionend}
        style={{
          transition: 'opacity 1s',
          opacity: this.state.show ? '1' : '0',
        }}
      >
        content
      </View>
    );
  }
};

聚合组件,利用这个组件的createComp可以快速的创建一个Comp组件

import React from 'react';
import { View } from '@tarojs/components';
import Comp from '../Comp';

export default class Group extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      comp: null,
    };
  }

  createComp() {
    const onHide = () => {
      this.destoryComp();
    }
    this.setState({
      comp: {
        onHide,
      },
    });
  }

  destoryComp() {
    this.setState({
      comp: null,
    });
  }

  render() {
    return (
      <View>
        {
          !!this.state.comp && <Comp {...this.state.comp} />
        }
      </View>
    )
  }
};

页面级组件: pages/index/index

export default class Index extends React.Component {
  constructor(props) {
    super(props);
    this.ref = React.createRef();
  }

  componentDidMount() {
    setTimeout(() => {
      this.ref.current.createComp();
    }, 2000);
  }
  

  render() {
    return (
      <View className={styles.container}>
        <Group
          ref={this.ref}
        />
        <Button
          onClick={() => {
            this.ref.current.createComp();
          }}
        >
          点击生成comp
        </Button>
      </View>
    )
  }
}

如何重现

运行代码,等待两秒后,未出现transition动画

或者删去componentDidMount代码,直接通过点击按钮

期望结果

能正确触发onTransitionend

实际结果

在部分场景下无法正确触发,且表现上看起来像是组件并非更新,而是产生了一个新节点(百度最新开发者工具3.28.1 swan element调试中保持节点层级可见时可以看见创建了2个id相同的节点)

环境信息

Taro v3.1.4


  Taro CLI 3.1.4 environment info:
    System:
      OS: Windows 10
    Binaries:
      Node: 10.16.3 - C:\Program Files\nodejs\node.EXE
      Yarn: 1.22.4 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
      npm: 6.9.0 - C:\Program Files\nodejs\npm.CMD

补充信息

重现步骤中引入位置请根据实际项目结构位置引入

代码转成支付宝小程序表现正常

几个能够使百度小程序表现正常的操作(各操作独立)

  1. 在页面级组件的componentDidMount中先执行一次createComp
  componentDidMount() {
    this.ref.current.createComp();
    setTimeout(() => {
      this.ref.current.createComp();
    }, 6000);
  }
  1. 在Group组件的render方法中,额外增加一个节点
  render() {
    return (
      <View>
        <View>group</View>
        {
          !!this.state.comp && <Comp {...this.state.comp} />
        }
      </View>
    )
  }
@yuzhounanhai
Copy link
Author

不知道是否有大佬在研究这个问题

@bluescurry
Copy link
Contributor

bluescurry commented May 17, 2021

@yuzhounanhai 您好,请问您是在使用taro3编译百度小程序吗,想问问您遇到了 flex: 1 不支持的情况了吗,如果有的话请问是如何解决的,万分感谢!!!

@yuzhounanhai
Copy link
Author

@yuzhounanhai 您好,请问您是在使用taro3编译百度小程序吗,想问问您遇到了 flex: 1 不支持的情况了吗,如果有的话请问是如何解决的,万分感谢!!!

百度小程序在这块确实令我心累,首先taro的其他issue中,相关维护者已经回答了flex:1不支持的原因:百度小程序的template是一个真实存在的节点,但是在ide的控制台中不可见,但是又真实存在。因此会出现诸如以下的结构:

<view>
  <template>
    <view/>
  </template>
</view>

此时最外层view设置 display:flex;, 最内层view设置 flex: 1;,那肯定无法生效,因为最内层view的父级节点是template,而template并不是flex弹性盒。

同理,在这样的情境下,width: 100%也将会失效。

知道了这个原因,要去解决其实也比较简单,也就是需要额外增加以下样式:

view > template {
  display: flex;
  flex: 1;
}

手动给template附加兼容性样式,可以在一定程度上解决这个问题(其他小程序template并不存在,因此这些样式并不会生效)。但是这依旧不美观。解决的根本还是要百度小程序官方出力。

如果你亦是使用taro进行多个平台小程序的开发,可以采用我的这一方式。

样式文件拆成2份,其中一份书写正常表现的样式,并引入百度小程序兼容样式文件。

以less为例

index.less

.container {
  display: flex;
  .lastitem {
    flex: 1;
  }
}
@import './index.patch.less';

index.patch.less

.container > template {
  display: flex;
  flex: 1;
}

这样的方式能保证你的代码在多平台小程序的统一程度,当然,如若你只专注于百度小程序的开发,可以考虑尝试其他布局。

该方案仅供参考。

另外使用真机调试时可以在开发者工具弹出来的窗口上看到完整的节点结构信息,你可以看到究竟有多少个template在作怪。

希望能在一定程度上帮助到你。

@bluescurry
Copy link
Contributor

@yuzhounanhai 您好,请问您是在使用taro3编译百度小程序吗,想问问您遇到了 flex: 1 不支持的情况了吗,如果有的话请问是如何解决的,万分感谢!!!

百度小程序在这块确实令我心累,首先taro的其他issue中,相关维护者已经回答了flex:1不支持的原因:百度小程序的template是一个真实存在的节点,但是在ide的控制台中不可见,但是又真实存在。因此会出现诸如以下的结构:

<view>
  <template>
    <view/>
  </template>
</view>

此时最外层view设置 display:flex;, 最内层view设置 flex: 1;,那肯定无法生效,因为最内层view的父级节点是template,而template并不是flex弹性盒。

同理,在这样的情境下,width: 100%也将会失效。

知道了这个原因,要去解决其实也比较简单,也就是需要额外增加以下样式:

view > template {
  display: flex;
  flex: 1;
}

手动给template附加兼容性样式,可以在一定程度上解决这个问题(其他小程序template并不存在,因此这些样式并不会生效)。但是这依旧不美观。解决的根本还是要百度小程序官方出力。

如果你亦是使用taro进行多个平台小程序的开发,可以采用我的这一方式。

样式文件拆成2份,其中一份书写正常表现的样式,并引入百度小程序兼容样式文件。

以less为例

index.less

.container {
  display: flex;
  .lastitem {
    flex: 1;
  }
}
@import './index.patch.less';

index.patch.less

.container > template {
  display: flex;
  flex: 1;
}

这样的方式能保证你的代码在多平台小程序的统一程度,当然,如若你只专注于百度小程序的开发,可以考虑尝试其他布局。

该方案仅供参考。

另外使用真机调试时可以在开发者工具弹出来的窗口上看到完整的节点结构信息,你可以看到究竟有多少个template在作怪。

希望能在一定程度上帮助到你。

感谢您的耐心解答,通过给 template 标签增加样式方案可以临时解决这个问题!虽然不是长期方案,但至少是可行的,再次感谢,最后还是希望百度小程序/taro尽快给出官方的解决方案。

@lp13762436965
Copy link

序的templa

@yuzhounanhai 您好,请问您是在使用taro3编译百度小程序吗,想问问您遇到了 flex: 1 不支持的情况了吗,如果有的话请问是如何解决的,万分感谢!!!

百度小程序在这块确实令我心累,首先taro的其他issue中,相关维护者已经回答了flex:1不支持的原因:百度小程序的template是一个真实存在的节点,但是在ide的控制台中不可见,但是又真实存在。因此会出现诸如以下的结构:

<view>
  <template>
    <view/>
  </template>
</view>

此时最外层view设置 display:flex;, 最内层view设置 flex: 1;,那肯定无法生效,因为最内层view的父级节点是template,而template并不是flex弹性盒。

同理,在这样的情境下,width: 100%也将会失效。

知道了这个原因,要去解决其实也比较简单,也就是需要额外增加以下样式:

view > template {
  display: flex;
  flex: 1;
}

手动给template附加兼容性样式,可以在一定程度上解决这个问题(其他小程序template并不存在,因此这些样式并不会生效)。但是这依旧不美观。解决的根本还是要百度小程序官方出力。

如果你亦是使用taro进行多个平台小程序的开发,可以采用我的这一方式。

样式文件拆成2份,其中一份书写正常表现的样式,并引入百度小程序兼容样式文件。

以less为例

index.less

.container {
  display: flex;
  .lastitem {
    flex: 1;
  }
}
@import './index.patch.less';

index.patch.less

.container > template {
  display: flex;
  flex: 1;
}

这样的方式能保证你的代码在多平台小程序的统一程度,当然,如若你只专注于百度小程序的开发,可以考虑尝试其他布局。

该方案仅供参考。

另外使用真机调试时可以在开发者工具弹出来的窗口上看到完整的节点结构信息,你可以看到究竟有多少个template在作怪。

希望能在一定程度上帮助到你。

你好, 我这里碰到一个问题,就是用Taro 3.3开发百度小程序, 然后setTimeout 实现倒计时功能, 但是页面不会刷新, 就一直是一个数字,但是控制台打印出来的数字是递增的, 试了taro 2.x 和 1.x 都没问题, 请问您碰到过这个问题吗

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
F-react Framework - React T-swan Target - 编译到百度小程序 V-3 Version - 3.x
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants