Как передать объект интерфейса и какого-либо другого типа функциональному компоненту в React?

#reactjs #typescript #react-functional-component

Вопрос:

Допустим, у меня есть интерфейс

 interface Setting {
    desc: string,
    title: string,
    value: string | number | boolean | number[] | float,
    value_type: "string" | "integer" | "bool" | "list" | "float"
}
 

И функциональный компонент, который принимает два аргумента

 const SettingsOption = ({ ...option }: Setting, test: string): JSX.Element => {return (...)}
 

Такая сигнатура функции кажется компилятору TypeScript прекрасной.

Затем я пытаюсь вызвать компонент с помощью <SettingsOption {...option} test=""/> , но он говорит

 type '{ test: string; desc: string; title: string; value: string | number | boolean | number[]; value_type: "string" | "float" | "integer" | "bool" | "list"; }' is not assignable to type 'IntrinsicAttributes amp; Setting'.
  Property 'test' does not exist on type 'IntrinsicAttributes amp; Setting'.ts(2322)
 

Мой вопрос: есть ли способ вызвать такой компонент с передачей всей необходимой информации?

Ответ №1:

Вы должны обратить внимание на некоторые моменты.

  1. В функциональных компонентах React первым параметром является реквизит компонента, а вторым-пересылка ссылок компонентам DOM.
  2. Все свойства, которые вы передадите в элементе JSX, будут получены как porps в компоненте.

Поэтому у вас не может быть test второго параметра. Также, если вы используете test в качестве свойств элемент JSX, SettingsOption получите его в реквизитах. Из-за этого вы получаете эту ошибку.

 interface Setting {
    desc: string,
    title: string,
    test: string;
    value: string | number | boolean | number[] | float,
    value_type: "string" | "integer" | "bool" | "list" | "float"
}
 
 const SettingsOption = ({ ...option }: Setting): JSX.Element => {return (...)}
 

В качестве альтернативы вместо использования функционального компонента в качестве элемента вы можете вызвать его как функцию и передать все необходимые аргументы:

 return (
    <div>
        {SettingsOption(option, "test")}
    </div>
)
 

Но этот подход может привести к росту Rendered more times than during previous render , если ваш компонент использует крючки.

Ответ №2:

Вы не можете этого сделать, потому что первый параметр-это объект props, а второй параметр-ссылка на API React.forwardRef. Но вы можете использовать оператор rest, например:

 interface Setting {
    desc: string,
    title: string,
    value: string | number | boolean | number[] | float,
    value_type: "string" | "integer" | "bool" | "list" | "float",
    test: string
}
const SettingsOption = ({test, ...option }: Setting): JSX.Element => {return (...)}