【问题标题】:React + Typescript referencing select element using useRef and forwardRefReact + Typescript 使用 useRef 和 forwardRef 引用选择元素
【发布时间】:2021-01-10 16:58:36
【问题描述】:

我有一个使用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>
    )
  }
)

非常感谢。

【问题讨论】:

  • but does not work when I programmatically set, so I am using useRef hook to get the value - 如果是这种情况,您应该找出为什么设置该值不会更改&lt;select&gt; .. 值,而不是尝试使用useRef 修复它。当您将useState 变量用于&lt;select&gt;... 元素的value 时,它将对状态变量(setValue(..)))的更改做出反应,因此您的问题可能出在&lt;DropdownSelect&gt;.. 组件中。来源:@987654321 @
  • @BennettDams select 值确实会发生变化,并且通过编程我的意思是它的选项取决于另一个父选择元素,因此当它的父选项更改时,它的值会自动更新。假设它的选定值是9 并且父选项更改它的值将更改为1。但是当我尝试linkRef.current.value 时,它会给出9 而不是新值1。对不起,如果我一开始不清楚。
  • 和@BennettDams 在上述情况下我尝试使用useStateonChange 事件从未被触发。当我尝试使用鼠标时它起作用了。

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


【解决方案1】:

我要在这里更改很多东西。首先,@BennettDams 正确地评论说使用 refs 确实不是解决这个问题的最佳方式。事实上,您可能会看到这个警告,告诉您不要这样做。

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

转发 ref 时,您需要将 ref 直接传递给 DOM 元素或转发 ref 的组件。所以你可以在select上设置ref={ref},但我不确定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>
  );
};

【讨论】:

    猜你喜欢
    • 2022-12-31
    • 2023-01-03
    • 2021-09-10
    • 2020-01-26
    • 2021-01-05
    • 2020-05-09
    • 2019-01-23
    • 2021-12-05
    • 2020-01-01
    相关资源
    最近更新 更多