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

Starting from version 10.20 will cause the order of child elements to be reversed #4405

Closed
ShaoGongBra opened this issue Jun 7, 2024 · 18 comments

Comments

@ShaoGongBra
Copy link

For example, if written like this, the actual rendering result will be text at the back and icons at the front
微信截图_20240607114524

Many places with judgment criteria will encounter similar problems

@ShaoGongBra
Copy link
Author

The normal way of rendering is like this
微信截图_20240607114714

@ShaoGongBra ShaoGongBra changed the title Starting from version 10.2 will cause the order of child elements to be reversed Starting from version 10.20 will cause the order of child elements to be reversed Jun 7, 2024
@rschristian
Copy link
Member

As our issue template requests, please provide a reproduction. It allows us to help you all the quicker.

@ShaoGongBra
Copy link
Author

As our issue template requests, please provide a reproduction. It allows us to help you all the quicker.

Because it is a pre act used on the WeChat mini program side in Taro, it is not easy to provide examples. In the webpage, I am not sure if such a problem will occur

@rschristian
Copy link
Member

In the webpage, I am not sure if such a problem will occur

This is why we require a minimum reproduction though, if you're not sure it can even be replicated on a webpage, that makes our job quite a bit harder.

And 10.19.7 is fine? It's 10.20.0 that's the issue? That'd point the issue to #4312

@ShaoGongBra
Copy link
Author

Yes, there is no problem with 10.19.7. I have tried versions up to 10.20.0 and later and have encountered this issue

在网页中,我不确定是否会出现这样的问题

这就是为什么我们需要最低限度的复制,但如果你不确定它是否可以在网页上复制,这会使我们的工作变得更加困难。

10.19.7 可以吗?这是 10.20.0 的问题所在吗?这会将问题指向#4312

@JoviDeCroock
Copy link
Member

Hey!

I wrote #4312 and I would love to get to the bottom of this with you so there are a few things that we need to understand before we can give pointers for a minimal reproduction (PS: I highly encourage you to try creating one either way).

The changed code in 10.20.0 only triggers in the following scenario: We diff and no DOM node is produced by for instance returning null, then we see that the oldVNode that used to be in that position is equal to our last pointer, that means we need to leave the gap intact and move our pointer to the next VNode.

In the latest version this check has evolved to just checking whether our oldDom is present in the view.

I am doubtful whether this is the root-cause of this inconsistency mainly because it looks like you're saying it is wrong from the first render, or am I misunderstanding that? Nor are your returning null so that would also make me doubt whether this is the root-cause.

Do you have a runtime that is imitating the DOM? It might not implement the isConnected property which might make this check fire more than it needs to which might lead to this inconsistency? If you can't reproduce this in a browser the aforementioned case might be applicable here. All though in 10.20.0 we only rely on internal properties so you might need to do some digging here on your end to reproduce this.

My main goal here is that you can look at the scenario that triggers this check, i.e. a list shrinking by adding a null in a certain position, and extrapolating it to your case.

@ShaoGongBra
Copy link
Author

What you said should be correct. It shouldn't be a problem that occurs during the first rendering because my icon is loaded asynchronously, so it will be re rendered after the icon is successfully loaded, and most of the problems seem to occur in the area with the icon,

My icon assembly is written as follows

import { Text } from '@tarojs/components'
import { useMemo } from 'react'
import { font, px } from '@/duxapp/utils'
import icons from './icons.json'
import './index.scss'

font.load('PlayerIcon', 'https://pictcdn.client.jujiang.me/fonts/PlayerIcon.1715861528075.ttf')

export const PlayerIcon = ({ name, color, size, style, className, ...props }) => {

  const _style = useMemo(() => {
    const sty = { ...style }
    if (color) {
      sty.color = color
    }
    if (size) {
      sty.fontSize = px(size)
    }
    return sty
  }, [color, size, style])

  const status = font.useFont('PlayerIcon')

  if (!icons[name]) {
    return console.log(`PlayerIcon的${name}图标不存在`)
  }

  if (!status) {
    return null
  }

  return <Text
    className={`PlayerIcon${className ? ' ' + className : ''}`}
    style={_style}
    {...props}
  >
    {String.fromCharCode(icons[name])}
  </Text>
}

@ShaoGongBra
Copy link
Author

This icon is automatically rendered after successful loading, and in some cases, I change the state by clicking on the event, which can also cause the order of the child elements to be rearranged. The code looks like this

export const WeappTelLogin = ({
  onLogin,
  onCancel,
  onSkip
}) => {

  const [check, setCheck] = useState(false)

  const getPhoneNumber = useCallback(e => {
    if (e.detail.errMsg === 'getPhoneNumber:ok') {
      cmsUser.weappTelLogin(e.detail.code).then(data => {
        onLogin(data)
      })
    } else {
      onSkip()
    }
  }, [onLogin, onSkip])

  return <View className='cms-login-weapp--mask inset-0 absolute'>
    <View className='cms-login-weapp'>
      <View className='cms-login-weapp__head'>
        <CmsIcon name='guanbi1' size={36} color='#fff' />
        <Text className='cms-login-weapp__head__name'>登录</Text>
        <CmsIcon name='guanbi1' size={36} color={duxappTheme.textColor1} onClick={onCancel} />
      </View>
      {/* After clicking on the event, the Row component below will actually be rendered at this location */}
      {
        check ?
          <Button size='l' type='primary' openType='getPhoneNumber' className='button-clean' onGetPhoneNumber={getPhoneNumber}>快捷登录</Button> :
          <Button size='l' type='primary'
            onClick={() => confirm({
              content: '请阅读并勾选同意隐私政策',
              cancel: false,
              confirmText: '知道了'
            })}
          >快捷登录</Button>
      }
      <Text className='cms-login-weapp__tel' align='center' size={2} onClick={onSkip}>手机号登录</Text>

      {/* After clicking on the event, the Row here will be moved up two lines during actual rendering */}
      <Row items='center' className='gap-2 mt-3' justify='center'>
        {/* The Radio component includes an icon component */}
        <Radio checked={check} onClick={() => setCheck(!check)} />
        <Row>
          <Text>阅读并同意</Text>
          <Text type='danger' onClick={() => nav('duxcms/common/richtext?url=member/agreement&title=用户协议')}>《隐私政策》</Text>
        </Row>
      </Row>
    </View>
  </View>
}

@JoviDeCroock
Copy link
Member

JoviDeCroock commented Jun 8, 2024

This is a custom react-reconciler though, not sure how that works with Preact 😅 I need a web reproduction, not how your components look, I'm sorry. I do notice that your ternary there doesn't have an else case so naively you can do check ? jsx : null which could be the issue here, as you also seem to have a case where you return void.

To re-iterate, if you don't go through the effort of making a reproduction I don't see how I can help you.

@ShaoGongBra
Copy link
Author

ShaoGongBra commented Jun 8, 2024

I have created an example code. Please check this repository and run the yarn dev:weapp --app=test command after installing the dependencies. Then use the WeChat developer tool (download here: https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html )Open the dist/weapp directory for preview
https://github.com/ShaoGongBra/preacttest

@ShaoGongBra
Copy link
Author

code location
home: src/test/pages/index/pages/home.jsx
login: src/duxcmsUser/components/user/login.jsx line 426

@ShaoGongBra
Copy link
Author

preact version
src/duxapp/app.json line 48
Please modify the version here, otherwise it will not take effect. After the modification, restart the command yarn dev:weapp --app=test

@rschristian
Copy link
Member

Then use the WeChat developer tool (download here: https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html)

In case it wasn't clear, we need a web reproduction. The link you've provided is entirely in Chinese (which none of the core team speaks) and requires we set up a very niche environment just to try to reproduce your issue. This is asking far too much of those volunteering time to help, I hope you understand.

If you can reproduce this issue in a web environment we can take a look.

Open the dist/weapp directory for preview https://github.com/ShaoGongBra/preacttest

This is a massive repo, we'd need a minimal reproduction, i.e., the bare minimum code needed to showcase the issue. Please cut this down to just a few files.

@ShaoGongBra
Copy link
Author

For this repository, you can only view the content of this file and the icon assembly. I cannot provide you with sample code in the web environment because I only used React in the WeChat environment to reduce the size of React packaging

https://github.com/ShaoGongBra/preacttest/blob/main/src/test/pages/index/pages/home.jsx

@rschristian
Copy link
Member

For this repository, you can only view the content of this file and the icon assembly.

Please reduce the repository down to just this then.

I cannot provide you with sample code in the web environment because I only used React in the WeChat environment

It's not likely we'll be able to help in that case; this is a lot to ask of maintainers.

@ShaoGongBra
Copy link
Author

This developer tool, you select the corresponding system download, install it,

  1. Please select tourist mode
    2 Click on the plus sign
  2. Click on the icon on the right side of the directory and select the directory dist/weapp
    4 Click OK
    5 Completed

WX20240608-184204
WX20240608-184222
WX20240608-184237

@JoviDeCroock
Copy link
Member

JoviDeCroock commented Jun 8, 2024

@ShaoGongBra I am reluctant to entertain this issue, frankly you are being disrespectful and you have no regard for what we tell you to do.

All of us work on Preact in our spare time and try to help everyone to the best of our ability. When we need to invest hours of that time into one persons issue that is very unfair to others. The issue here even has a custom reconciler and non standard tools.

All we ask is for a minimal way to reproduce this, on web, with a common tool like vite. You can use stackblitz/... I won't dig through multiple levels of libraries just to uncover that taro does not i.e. have a correct dom implementation/...

I went through the time to give you pointers as well as identify a mistake in your code, yet you throw more unrelated stuff at us.

@rschristian
Copy link
Member

While we're always happy to see users utilizing Preact in non-standard/non-supported environments, unfortunately there's little we can do when you run into issues that cannot be reproduced in a web environment. There's simply far too many things that can go wrong that are outside the scope of Preact, and investing hours of time (for free) into niche tooling (and tooling that we'd have to constantly be using translation services just to work with) isn't fair to maintainers.

We'd love to help, but you need to do some work first to set up a minimal reproduction in an environment we actually support; WeChat and custom reconcilers are not supported.

As such, I'll close this out. If you do get a valid reproduction together then we can re-open and take another look.

@rschristian rschristian closed this as not planned Won't fix, can't repro, duplicate, stale Jun 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants