最新消息:20181230 VPS服务器已从Linode换到腾讯云香港,主题仍用朋友推荐的大前端D8

【未解决】Preact中用spring-picker去实现弹框选择

Preact crifan 699浏览 0评论

折腾:spring-picker

【已解决】ReactJS中如何弹出列表选择框

期间,去试试用spring-picker:

springalskey/picker: react mobile picker选择器,一级、二级联动,三级联动城市选择器

效果如何。

➜  ucowsapp git:(master) ✗ npm install spring-picker -S
npm WARN preact-boilerplate@6.0.0 No repository field.
npm WARN preact-boilerplate@6.0.0 No license field.
added 6 packages in 13.676s

然后调试了半天:

import style from ‘./style.less’;
import ‘spring-picker/lib/style.css’;
import { Picker, Popup } from ‘spring-picker’;
export default class EstrusManagement extends Component {
  state = {
    userPickerVisible : true,
    defaultValue: {name: ‘Lincal’, value: 5},
    …
  };
  userData =  {
    list: [
      {name: ‘杜保坤’, value: 0},
      {name: ‘况宏瑞’, value: 1},
。。。
      {name: ‘小泥巴’, value: 11}
    ],
    defaultValue: this.state.defaultValue,
    displayValue (item) {
      return item.name;
    }
  };
  handleChangeUser (data) {
    data = data || {};
    this.userData.defaultValue = data;
    this.setState({defaultValue: data});
  }
  closeUserPicker () {
    this.setState({userPickerVisible: false});
  }
  cancelUserPicker () {
    this.userData.defaultValue = {};
    this.setState({
      userPickerVisible: false,
      defaultValue: {}
    });
  }
   return (
      ……
        <div className = "picker-demo">
          <div className="item">
            { this.state.defaultValue.name }
          </div>
          <div className="single-picker">
            <Popup
              onCancel={this.cancelUserPicker.bind(this)}
              onConfirm={this.closeUserPicker.bind(this)}
              visible={this.state.userPickerVisible}>
              <Picker
                onChange={this.handleChangeUser.bind(this)}
                data={this.userData}
              />
            </Popup>
          </div>
        </div>

结果还是无法显示:

后来想起来了:

貌似是:

自己此处的style,都是:

class={style.xxxx}

去引用的,而别人的代码是className=“xxx”

所以去改为:

        <div class={style.picker_demo}>
          <div class={style.item}>
            { this.state.defaultValue.name }
          </div>
          <div class={style.single_picker}>
            <Popup
              onCancel={this.cancelUserPicker.bind(this)}
              onConfirm={this.closeUserPicker.bind(this)}
              visible={this.state.userPickerVisible}>
              <Picker
                onChange={this.handleChangeUser.bind(this)}
                data={this.userData}
              />
            </Popup>
          </div>
        </div>

当然,对应的style样式,都已拷贝过来了:

style.less

.picker_demo {
  text-align: center;
  .button_wrap {
    margin: 10px;
  }
  .item {
    width: 100%;
    height: 44px;
    line-height: 44px;
  }
}

结果还是无法显示。

后来无意间去对比:

官网的demo:

(通过参考:

springalskey/picker: react mobile picker选择器,一级、二级联动,三级联动城市选择器

中的:

# install dependencies
npm install
# run server
npm start

运行出来了demo:

和自己此处的运行的结果中的元素:

去比较:

好像也没什么差别啊

然后的然后,无意间点击了Chrome调试窗口右边的styles中的

此处的modal窗口的一个position属性,去掉了该属性后,结果竟然就看到了此处的弹框列表:

然后再去试试去掉top,结果就可以正常显示在底部了:

-》此时,很高兴,至少可以显示出来了。

-》然后以为是 布局方面的问题,以为接下来要去调试布局,就可以了

-》但是期间在找样式style方面的配置时,发现个现象:

对于此处的,官网给出实例中single-picker

官网自己的实例代码中,都找不到:

-》然后结果更好玩(诡异,郁闷的)是,去把此处自己代码中的:

class={style.single_picker}

去掉后:

        <div class={style.picker_demo}>
          <div class={style.item}>
            { this.state.defaultValue.name }
          </div>
          <div>
            <Popup
              onCancel={this.cancelUserPicker.bind(this)}
              onConfirm={this.closeUserPicker.bind(this)}
              visible={this.state.userPickerVisible}>
              <Picker
                onChange={this.handleChangeUser.bind(this)}
                data={this.userData}
              />
            </Popup>
          </div>
        </div>

以为可以显示了

其实不是,其实是刚才把top属性去掉后才可以显示的。

所以此处去看看看对应的css:

node_modules/spring-picker/lib/style.css

是此处的top属性导致无法显示的。

然后专门去看了看对应的css中的配置:

然后就可以正常显示了:

但是又出其他问题了:

此处点击取消 没反应,点击确定结果调用了handleChangeUser

然后感觉像是:

官网的demo中,运行时有警告提醒:

【已解决】运行spring-picker的demo中出现警告:Warning string refs are not supported on children of TransitionGroup

但是诡异的是:

那也最多是:

此处点击取消和确定,都应该没反应才对啊。

不应该是 取消没反应但确定却却调用(当滚动导致选择发生变化时才会调用的)handleChangeUser

看到是:

此处上面的css等布局内部错位

导致点击确定 等价于 点击了切换用户了?

然后去换用Mac中的Safari试试:

模拟iPhone看看效果:

第一次,点击 取消 或 确定,都是可以看到正常显示或消失的:

但是之后再进去,结果按钮就无效,就无法显示和消失了:

后来发现,Mac中的Chrome也是同样的现象。

第一次,两个按钮都可以

后来就不可以。

算了,去整个优化本身页面中的代码,确保点击每个处理,都可以弹出页面,再看看是否正常

结果问题依旧:

还是第二次进入后,虽然点击按钮都可以接受到事件,函数被调用

但是窗口没有消失

感觉是:

第二次,对于modal窗口不消失了?

react js modal not dismiss

现在去调试,看看第一次正常弹框消失时的输出:

再去看看,第二次弹框不消失时候的现象:

看起来是:第二次BaseModal中,render没有被调用。

react js modal render not call

后来调试是第二次时:

BaseModal componentDidUpdate

就没有被调用过

之后就去:

【记录】ReactJS中参考spring-picker自己去实现弹框选择

【后记】

通过自己参考其代码,完整的写了一遍逻辑,调试后得知:

上述第二次进入页面,弹框就无法消失,导致此问题的相关代码是:

picker/src/components/modal/BaseModal.jsx

  componentDidUpdate () {
    if (this.refs.modalOverlay && !this.refs.modalOverlay.onclick) {
      // 点击阴影背景时cancel() popup
      this.refs.modalOverlay.onclick = (e) => {
        e.stopPropagation();
        this.props.onCancel && this.props.onCancel();
      }
      // 点击modal阻止默认行为
      // 原理:react event listener中无法阻止原生事件,所以用原生事件来替代react事件
      this.refs.modal.onclick = (e) => e.stopPropagation();
    }
  }

总之就是和:

e.stopPropagation();

有关系

但是具体是怎么导致第二次无法消失的具体机制,暂时没空去研究了。有空再研究。

转载请注明:在路上 » 【未解决】Preact中用spring-picker去实现弹框选择

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
63 queries in 0.075 seconds, using 10.03MB memory