react-component / m-picker

React Mobile Picker(web & react-native)

Home Page:http://react-component.github.io/m-picker/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Popup和Picker结合使用时,.getValue()报错,picker对象中没有此方法? this.props.onOk!(this.picker && this.picker.getValue())

slsay opened this issue · comments

PopupMixin.tsx line:116

Popup和Picker结合使用时,.getValue()报错,picker对象中没有此方法?

import Picker from 'rmc-picker/lib/Picker'
import PopPicker from "rmc-picker/lib/Popup";

...
    const items = ["1", "2", "3", "4", "5" ,"6" ,"7"];
    const popupContent = (
      <Picker
      >
        {
          items.map((item) => {
            return <Picker.Item value={item} key={generateUUID()}>
            {item}
            </Picker.Item>
          })
        }
      </Picker>
    );
    
   const picker = (
        <PopPicker
          transitionName="rmc-picker-popup-slide-fade"
          maskTransitionName="rmc-picker-popup-fade"
          picker={popupContent}
          okText="OK"
          dismissText="取消"
          title="选择"
          value={value}
          pickerValueChangeProp="onValueChange"
          pickerValueProp="selectedValue"
          onOk={this.handleSelectChange}
        >
          <div >
            <div >
              <span>{value}</span>
              <span>
                <Icon type="down" theme="outlined" />
              </span>
            </div>
          </div>
        </PopPicker>
);
...

@yiminghe 同样问题,正在找原因

我今天也遇到了这个问题,看了下源码,发现问题出现在popupmixin.js中

  getContent = () => {
      if (this.props.picker) {
        let { pickerValue } = this.state;
        if (pickerValue === null) {
          pickerValue = this.props.value;
        }
        return React.cloneElement(this.props.picker, ({
          [this.props.pickerValueProp!]: pickerValue,
          [this.props.pickerValueChangeProp!]: this.onPickerChange,
          ref: this.saveRef,
        }));
      } else {
        return this.props.content;
      }
    }

这里的this.props.picker 实际上是PickerMixin高阶组件返回的组件,并不是实际的picker。由于ref这个key不能在父子组件中传递,所以ref指向了一个wrapperComponent,getValue方法是不存在的。建议不要使用ref作为key,继续使用saveRef传递到实际的picker组件中。

我今天也遇到了这个问题,看了下源码,发现问题出现在popupmixin.js中

  getContent = () => {
      if (this.props.picker) {
        let { pickerValue } = this.state;
        if (pickerValue === null) {
          pickerValue = this.props.value;
        }
        return React.cloneElement(this.props.picker, ({
          [this.props.pickerValueProp!]: pickerValue,
          [this.props.pickerValueChangeProp!]: this.onPickerChange,
          ref: this.saveRef,
        }));
      } else {
        return this.props.content;
      }
    }

这里的this.props.picker 实际上是PickerMixin高阶组件返回的组件,并不是实际的picker。由于ref这个key不能在父子组件中传递,所以ref指向了一个wrapperComponent,getValue方法是不存在的。解决办法是不能使用ref作为key,继续使用saveRef传递到实际的picker组件中。

看到m-date-picker里也有使用picker组件,应该也是有问题的吧

@slsay 我也遇到同樣的問題,而我是參考 rmc-date-picker 的寫法解決:
注意到rmc-date-picker的底層也是用rmc-picker寫的:
DatePicker.tsx
Popup.tsx
作者在DatePicker中自定義getValue()
便可解決PopupMixin讀不到Picker內建getValue()的問題:

 getDate() {
    return this.clipDate(this.state.date || this.getDefaultMinDate());
  }

  // used by rmc-picker/lib/PopupMixin.js
  getValue() {
    return this.getDate();
  }

這裡的getValue()最後返回的是 DatePicker 的選取值
誠如 @OPY-bbt 大所言,起因應該是ref指向wrapperComponent導致getValue方法不存在所致

我的寫法

import PickerElement from 'rmc-picker/lib/Picker';
import Popup from 'rmc-picker/lib/Popup';
import PopupStyles from 'rmc-picker/lib/PopupStyles';

class Picker extends React.Component {
  state = {
    selectedValue: get(this.props, ['itemList', 0, 'value']),
  };

  getValue = () => {
    return this.state.selectedValue;
  };

  onValueChange = value => {
    this.setState({ selectedValue: value });
  };

  render() {
    const { disabled, itemList } = this.props;
    const selectedValue = get(this.state, 'selectedValue');
    return (
      <PickerElement
        onValueChange={value => this.onValueChange(value)}
        selectedValue={selectedValue}
        disabled={disabled}
      >
        {itemList.map(item => (
          <PickerElement.Item key={item.value} value={item.value}>
            {item.label}
          </PickerElement.Item>
        ))}
      </PickerElement>
    );
  }
}

const PopupPicker = props => {
  const { disabled, itemList, isVisible, children } = props;
  const onOk = get(props, 'onOk', noop);
  const onDismiss = get(props, 'onDismiss', noop);
  return (
    <Popup
      picker={<Picker disabled={disabled} itemList={itemList} />}
      styles={PopupStyles}
      okText={確定}
      dismissText={取消}
      onOk={value => onOk(value)}
      onDismiss={onDismiss}
      visible={isVisible}
    >
      {children}
    </Popup>
  );
};

export default PopupPicker;

供您參考

@yanghaochang104
谢谢你的例子。