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

小程序 MovableView 设置坐标后无法重新渲染 #1981

Closed
xuxiaoxiao312 opened this issue Jan 18, 2019 · 10 comments
Closed

小程序 MovableView 设置坐标后无法重新渲染 #1981

xuxiaoxiao312 opened this issue Jan 18, 2019 · 10 comments

Comments

@xuxiaoxiao312
Copy link

@xuxiaoxiao312 xuxiaoxiao312 commented Jan 18, 2019

问题描述
小程序中使用MovableView,移动后设置与之前相同的x,y坐标值无法重新渲染,this.setState和this.forceUpdate都无法重新,如果x,y值与之前不同就可以重新渲染
复现步骤

constructor(props) {
	super(...props);
	this.state = {
		test: [
			{
				top: 0,
				left: 0,
				contnet: '内容1'
			},
			{
				top: 100,
				left: 0,
				contnet: '内容222'
			}
		]
	};
}
changePosition() {
	this.forceUpdate();
}
render() {
	let { test } = this.state;
	return (
		<MovableArea style='height:200px;width:100%'>
			{test.map((el, i) => {
				return (
					<MovableView
						style='width:100px;height:50px'
						key={i}
						direction='all'
						x={el.left}
						y={el.top}
						onTouchEnd={this.changePosition}
					>
						<View> {el.contnet}</View>
					</MovableView>
				);
			})}
		</MovableArea>
	);
}
完整测试代码

系统信息
👽 Taro v1.2.0

Taro CLI 1.2.0 environment info:
System:
OS: macOS 10.14.1
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 8.12.0 - /usr/local/bin/node
Yarn: 1.10.1 - /usr/local/bin/yarn
npm: 6.4.1 - /usr/local/bin/npm

@taro-bot

This comment has been minimized.

Copy link

@taro-bot taro-bot bot commented Jan 18, 2019

欢迎提交 Issue~

如果你提交的是 bug 报告,请务必遵循 Issue 模板的规范,尽量用简洁的语言描述你的问题,最好能提供一个稳定简单的复现。🙏🙏🙏

如果你的信息提供过于模糊或不足,或者已经其他 issue 已经存在相关内容,你的 issue 有可能会被关闭。

Good luck and happy coding~

@xuxiaoxiao312

This comment has been minimized.

Copy link
Author

@xuxiaoxiao312 xuxiaoxiao312 commented Jan 22, 2019

@luckyadam 请问这个问题大概什么时候可以解决?

@luckyadam

This comment has been minimized.

Copy link
Contributor

@luckyadam luckyadam commented Jan 23, 2019

我这两天看下~

@xuxiaoxiao312

This comment has been minimized.

Copy link
Author

@xuxiaoxiao312 xuxiaoxiao312 commented Feb 14, 2019

我这两天看下~

请问这个问题有什么临时解决方案吗?

@javahuang

This comment has been minimized.

Copy link

@javahuang javahuang commented Feb 16, 2019

@luckyadam 同样遇到这个问题,请问有什么解决方案吗 @yuche

另外 MovableView,我想通过 onTouchStart 事件来设置 disabled 为 false,onTouchEnd设置 disabled 为 true,貌似也不行

@xuxiaoxiao312

This comment has been minimized.

Copy link
Author

@xuxiaoxiao312 xuxiaoxiao312 commented Feb 19, 2019

@luckyadam @yuche 这个问题要怎么解决呢,项目要上线了,就这里卡住了,页面比较复杂,小程序混写也不能只引用单个组件,请问能给个确切回复吗?

@luckyadam

This comment has been minimized.

Copy link
Contributor

@luckyadam luckyadam commented Feb 25, 2019

@xuxiaoxiao312 抱歉,我们这两天看下,最近确实很忙

@taro-bot

This comment has been minimized.

Copy link

@taro-bot taro-bot bot commented Feb 25, 2019

@Chen-jj

This comment has been minimized.

Copy link
Contributor

@Chen-jj Chen-jj commented Feb 28, 2019

@xuxiaoxiao312 原因有二:

一、小程序的 MovableView 是非可控组件,组件位置变更时 data 的 x 和 y 并不会跟随变化,还是初始值。

二、Taro 更新时会将新的数据和页面 data 作一次 diff,diff 出最小更新。onTouchEnd 时如果 setState 相同的坐标,diff 时发现和 data 中的坐标一样,就会跳过这次更新,所以就会出现你提出的 bug。

因此正确做法是在 onChange 的时候保证 state、data 中坐标值与当前 MovableView 的坐标值一致。

具体代码:

import Taro, { Component } from '@tarojs/taro'
import { View, MovableArea, MovableView } from '@tarojs/components'

export default class Detail extends Component {
  constructor(props) {
    super(...props);
    this.state = {
      test: [
        {
          top: 0,
          left: 0,
          content: '内容1'
        },
        {
          top: 100,
          left: 0,
          content: '内容222'
        }
      ]
    };
  }
  changePosition() {
    this.setState({
      test: [
        {
          top: 0,
          left: 0,
          content: '内容1'
        },
        {
          top: 100,
          left: 0,
          content: '内容222'
        }
      ]
    })
  }

  handleChange (i, e) {
    this.setState(prev => {
      const test = prev.test.slice()
      test[i] = {
        top: e.detail.y,
        left: e.detail.x,
        content: test[i].content
      }
      return { test }
    })
  }

  render() {
    let { test } = this.state;
    return (
      <MovableArea style='height:200px;width:100%'>
        {test.map((el, i) => {
          return (
            <MovableView
              style='width:100px;height:50px'
              key={i}
              direction='all'
              x={el.left}
              y={el.top}
              onTouchEnd={this.changePosition}
              onChange={this.handleChange.bind(this, i)}
            >
              <View> {el.content}</View>
            </MovableView>
          );
        })}
      </MovableArea>
    );
  }
}
@taro-bot

This comment has been minimized.

Copy link

@taro-bot taro-bot bot commented Feb 28, 2019

Hello~

您的问题楼上已经有了确切的回答,如果没有更多的问题这个 issue 将在 15 天后被自动关闭。

如果您在这 15 天中更新更多信息自动关闭的流程会自动取消,如有其他问题也可以发起新的 Issue。

Good luck and happy coding~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.