[英]How to type forwardRef in separate select component?
我使用的技術是 react、typescript 和 styled-components。 我正在嘗試創建 select 組件,以便在 React Hook Form 中使用它。 起初,看起來一切都是正確的,但我從 typescript 收到錯誤消息:
沒有重載匹配此調用。 重載 1 of 2, '(props: Pick<Pick<Pick<DetailedHTMLProps<SelectHTMLAttributes, HTMLSelectElement>, "form" |... 262 more... | "onTransitionEndCapture"> & {...; } & ISelectProps, "形式” |... 264 更多... | “選項”> & 部分<...>, “形式” |... 264 更多... | “選項”> & {...; } & { ...; }): ReactElement<...>',給出了以下錯誤。 類型“ForwardedRef”不可分配給類型“RefObject | (RefObject & ((instance: HTMLSelectElement | null) => void)) | (((實例:HTMLSelectElement | null) => void) & RefObject<...>) | ((((實例:HTMLSelectElement | null)=> void)&(((實例:HTMLSelectElement | null)=> void))| null | 不明確的'。 類型“MutableRefObject”不可分配給類型“RefObject | (RefObject & ((instance: HTMLSelectElement | null) => void)) | (((實例:HTMLSelectElement | null) => void) & RefObject<...>) | ((((實例:HTMLSelectElement | null)=> void)&(((實例:HTMLSelectElement | null)=> void))| null | 不明確的'。 類型 'MutableRefObject' 不可分配給類型 '((instance: HTMLSelectElement | null) => void) & RefObject'。 類型“MutableRefObject”不可分配給類型“(實例:HTMLSelectElement | null)=> void”。 類型“MutableRefObject”不匹配簽名“(實例:HTMLSelectElement | null):void”。
這是我的代碼:
import React, { forwardRef } from "react";
import styled from "styled-components";
import arrow from "../assets/svg/select_arrow.svg";
interface ISelectProps {
options?: { name: string; value: string | number }[];
name: string;
ref?:
| ((instance: HTMLSelectElement | null) => void)
| React.RefObject<HTMLSelectElement>
| null
| undefined;
}
const SelectContainer = styled.div`
display: flex;
align-items: center;
width: 100%;
position: relative;
`;
const StyledSelect = styled.select<ISelectProps>`
width: 100%;
height: 30px;
padding: 0 10px;
background: ${({ theme }) => theme.colors.transparentButton};
color: white;
border: 1px solid white;
border-radius: ${({ theme }) => theme.borderRadius};
font-size: 14px;
-moz-appearance: none; /* Firefox */
-webkit-appearance: none; /* Safari and Chrome */
appearance: none;
&:focus,
&:active {
outline: none;
}
`;
const StyledArrow = styled.img`
position: absolute;
right: 10px;
padding: inherit;
`;
const Select = forwardRef(({ options, name }: ISelectProps, ref) => {
return (
<>
<SelectContainer>
<StyledSelect name={name} ref={ref}>
{options?.map((op) => (
<option value={op.value}>{op.name}</option>
))}
</StyledSelect>
<StyledArrow src={arrow} />
</SelectContainer>
</>
);
});
export default Select;
codeandbox.io/s/eager-hertz-opbsi?file=/src/select.tsx
我究竟做錯了什么? 提前感謝所有有用的答案!
首先,在這種情況下, ref
不是 props 的一部分。 您應該為forwardRef
提供兩個通用參數以幫助 TS 縮小類型。
什么是ref
? 它只是 HTML 元素
import React, { forwardRef } from "react";
import styled from "styled-components";
interface ISelectProps {
options?: { name: string; value: string | number }[];
name: string;
}
const SelectContainer = styled.div`
display: flex;
align-items: center;
width: 100%;
position: relative;
`;
const StyledSelect = styled.select<ISelectProps>`
width: 100%;
height: 30px;
padding: 0 10px;
background: ${({ theme }) => theme.colors.transparentButton};
color: white;
border: 1px solid white;
border-radius: ${({ theme }) => theme.borderRadius};
font-size: 14px;
-moz-appearance: none; /* Firefox */
-webkit-appearance: none; /* Safari and Chrome */
appearance: none;
&:focus,
&:active {
outline: none;
}
`;
const StyledArrow = styled.img`
position: absolute;
right: 10px;
padding: inherit;
`;
const Select = forwardRef<HTMLSelectElement, ISelectProps>(({ options, name }, ref) => {
return (
<>
<SelectContainer>
<StyledSelect name={name} ref={ref}>
{options?.map((op) => (
<option value={op.value}>{op.name}</option>
))}
</StyledSelect>
</SelectContainer>
</>
);
});
export default Select;
您從未輸入過ref
object,請查看React TypeScript Cheatsheet - forwardRef
中的示例。
// T typing the ref
forwardRef<T, P = {}>(...)
// Full typing signature
function forwardRef<T, P = {}>(render: ForwardRefRenderFunction<T, P>): ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<T>>;
// BAD - ref object untyped
const Select = forwardRef(({ options, name }: ISelectProps, ref) => {...}
// GOOD - ref object typed
const Select = forwardRef<HTMLSelectElement, ISelectProps>(
({ options, name }, ref) => {...}
);
https://codesandbox.io/s/hungry-architecture-7gsnp?file=/src/select.tsx:665-1038
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.