React + Typescript使用useRef和forwardRef引用选择元素

时间:2020-09-24 11:47:55

标签: javascript reactjs typescript react-hooks styled-components

我有一个使用useRef钩子的主要组件,还有一个我使用forwardRef钩子和Select元素的子组件。我需要获取select元素的值。我可以在useState上使用onChange钩子,但是当我更改值时它可以工作,但是当我以编程方式进行设置时,它不起作用,所以我在使用useRef钩子来获取值。但是问题是,当我使用linkRef.current.value时,它不提供最新值,而是给出旧值。

通过编程,我的意思是它的选项取决于另一个父select元素,因此,当它的父选项更改时,其值会自动更新。假设它的选定值为 9 ,并且父选项更改了,它的值将更改为 1 。但是当我尝试linkRef.current.value时,它会给出 9 而不是新值 1

以下是我的代码示例:

主要组件

const linkRef = useRef<HTMLSelectElement>(document.createElement('select'))

const func = () => {
    console.log(linkRef)
}

<Dropdown
  props={props}
  ref={linkRef}
/>

下拉组件

import React, {
  forwardRef,
  Ref,
  MutableRefObject
} from 'react'
const Dropdown = forwardRef(
  (
    props: Props,
    ref: Ref<HTMLSelectElement>
  ) => {
    const {value,options} = props
    return ( 
     <DropdownSelect 
      value={value}
      ref={ref}
      >
       {
        options.map((option, i) => ( 
         <option value={option}> 
           {option} 
         </option>
        ))
      } 
      </DropdownSelect>
    )
  }
)

非常感谢。

1 个答案:

答案 0 :(得分:0)

我会在这里改变很多事情。首先,@ BennettDams正确地指出,使用引用并不是实现此目的的最佳方法。实际上,您可能会看到此警告,告诉您不要这样做。

警告:道具类型失败:您向表单字段提供了value道具 没有onChange处理程序。这将呈现一个只读字段。如果 该字段应可变使用defaultValue。否则,请设置 onChangereadOnly

转发参考时,您需要将参考直接传递给DOM元素或转发参考的组件。因此,您可以在ref={ref}上设置select,但是不确定DropdownSelect

看起来您的选择只是纯字符串?如果您可以为每个选项使用唯一键,React会更喜欢它。将选项作为对象还可以使您选择任何类型,而不仅仅是字符串。像这样:

interface Option<T> {
  key: string;
  value: T;
  label: string;
}

但是我不想让它变得太复杂,所以现在让我们坚持使用字符串。您想要的是这样的:

interface DropdownProps {
  value: string;
  onChangeValue(value: string): void;
  options: string[];
}

const Dropdown = (props: DropdownProps) => {
  const { value, options, onChangeValue } = props;
  return (
    <select value={value} onChange={(e) => onChangeValue(e.target.value)}>
      {options.map((option) => (
        <option key={option} value={option}>
          {option}
        </option>
      ))}
    </select>
  );
};