Reactjs 获取offsettop和offsetheight属性不会出错

Reactjs 获取offsettop和offsetheight属性不会出错,reactjs,typescript,Reactjs,Typescript,我正在获取选项。值属性没有错误不确定,但我认为这是关于引用的。我正在共享我的代码。请建议我做什么 代码:2 onClick={() => this.change(option.value)} key={option.value} 错误显示:2 (参数)选项:选项PropType “number”类型的参数不能分配给“string”类型的参数。ts 代码:3 <div className="dropdown-label">{current.l

我正在获取选项。值属性没有错误不确定,但我认为这是关于引用的。我正在共享我的代码。请建议我做什么

代码:2

onClick={() => this.change(option.value)}
        key={option.value}
错误显示:2
(参数)选项:选项PropType “number”类型的参数不能分配给“string”类型的参数。ts

代码:3

<div className="dropdown-label">{current.label}</div>
{current.label}
错误显示:3 恒定电流:选项PropType |未定义 对象可能为“未定义”。ts

下拉列表.tsx

import _ from "lodash";
import React, { Component, createRef } from "react";
import DropdownArrow from "../../assets/dropdown-arrow.svg";
import "./Dropdown.scss";

type OptionsPropType = {
  value: number;
  label: string;
};

interface IProps {
  value: any;
  height: number;
  options: Array<OptionsPropType>;
  onChange: (value: string) => void;
}

interface IState {
  isOpen: boolean;
  value: string;
}

export class Dropdown extends Component<IProps, IState> {
  private readonly listRef: React.RefObject<HTMLDivElement>;
  private readonly containerRef: React.RefObject<HTMLDivElement>;

  constructor(props:IProps) {
    super(props);
    this.state = {
      isOpen: false,
      value: props.value
    };
    this.listRef = createRef();
    this.containerRef = createRef();
  }

  change(value:string) {
    this.setState({ value });
    this.props.onChange(value);
    this.close();
  }

  onOutsideClicked = (e?:any) => {
    // only outside clicks allowed
    if (
      this.containerRef.current &&
      this.containerRef.current.contains(e.target)
    ) {
      return;
    }
    document.removeEventListener("mousedown", this.onOutsideClicked);
    this.close();
  };

  toggle() {
    const isOpen = !this.state.isOpen;
    this.setState({ isOpen });
    if (isOpen) {
      document.addEventListener("mousedown", this.onOutsideClicked);
    }
  }

  close() {
    this.setState({ isOpen: false });
  }

  componentDidRecieveProps(props:any) {
    if (props.value !== this.state.value) {
      this.setState({ value: props.value });
    }
  }

  componentDidUpdate() {
    if (this.listRef.current) {
      const option = this.refs["option-" + this.props.value];
      this.listRef.current.scrollTop =
        option.offsetTop - (this.props.height - option.offsetHeight) / 2;
    }
  }

  render() {
    const { value, isOpen } = this.state;
    const current = _.find(this.props.options, (option) => {
      // HACK because select returns string
      return option.value.toString() === value.toString();
    });

    const list = _.map(this.props.options, (option) => (
      <div
        ref={`option-${option.value}`}
        className={`dropdown-option ${
          value.toString() === option.value.toString()
            ? "dropdown-option--selected"
            : ""
        }`}
        onClick={() => this.change(option.value)}
        key={option.value}
      >
        {option.label}
      </div>
    ));

    return (
      <div
        className={`dropdown ${isOpen ? "dropdown--open" : ""}`}
        onClick={() => this.toggle()}
        ref={this.containerRef}
      >
        <div className="dropdown-label">{current.label}</div>
        <div className="dropdown-arrow">
          <img src={DropdownArrow} />
        </div>
        {/* <select onChange={(e) => this.change(e.target.value)} defaultValue={value}>{list}</select> */}
        {isOpen ? (
          <div
            className="dropdown-list"
            style={{ maxHeight: this.props.height + "px" }}
            ref={this.listRef}
          >
            {list}
          </div>
        ) : null}
      </div>
    );
  }
}
从“lodash”导入; 从“React”导入React,{Component,createRef}; 从“../../assets/dropdown arrow.svg”导入下拉箭头; 导入“/Dropdown.scss”; 类型选项PropType={ 值:数字; 标签:字符串; }; 接口IProps{ 价值:任何; 高度:数字; 选项:阵列; onChange:(值:string)=>void; } 界面状态{ 等参:布尔; 值:字符串; } 导出类下拉列表扩展组件{ 私有只读listRef:React.reObject; 私有只读容器ref:React.reObject; 建造师(道具:IProps){ 超级(道具); 此.state={ 伊索彭:错, 价值:道具价值 }; this.listRef=createRef(); this.containerRef=createRef(); } 更改(值:字符串){ this.setState({value}); this.props.onChange(值); 这个。关闭(); } onOutsideClicked=(e?:any)=>{ //只允许外部点击 如果( 此为.containerRef.current&& this.containerRef.current.contains(e.target) ) { 返回; } document.removeEventListener(“mousedown”,this.onOutsideClicked); 这个。关闭(); }; 切换(){ 常量isOpen=!this.state.isOpen; this.setState({isOpen}); if(等参线){ document.addEventListener(“mousedown”,this.onOutsideClicked); } } 关闭(){ this.setState({isOpen:false}); } ComponentDiReceiveProps(道具:任意){ if(props.value!==this.state.value){ this.setState({value:props.value}); } } componentDidUpdate(){ 如果(此.listRef.current){ const option=this.refs[“option-”+this.props.value]; this.listRef.current.scrollTop= option.offsetTop-(this.props.height-option.offsetHeight)/2; } } render(){ const{value,isOpen}=this.state; const current=uu.find(this.props.options,(option)=>{ //HACK,因为select返回字符串 返回选项.value.toString()==value.toString(); }); const list=\uu.map(this.props.options,(option)=>( this.change(option.value)} 键={option.value} > {option.label} )); 返回( this.toggle()} ref={this.containerRef} > {current.label} {/*this.change(e.target.value)}defaultValue={value}>{list}*/} {isOpen( {list} ):null} ); } } 完整项目链接

这是我在最后一个问题上没有为您解决的部分,因为这是一个非常麻烦的问题。他们在每个
选项上设置了一个ref,这些选项是存储在dictionary对象中的
字符串
ref,他们通过查找其键来访问ref。错误告诉您需要将它们更新为较新的引用,因为不支持
string
ref。与我们为列表和容器设置一个ref不同,我们需要一个
记录
refs对象,每个选项一个。:(还有其他方法吗?@LindaPaiste
const option:any=this.refs[“option-”+this.props.value];
此解决方案工作正常请给出代码:2和代码:3的解决方案