web-dev-qa-db-ja.com

TypeScriptのReduxフォームフィールドにカスタムプロパティを渡す

カスタムプロパティをRedux-Form-Fieldに渡したいのですが。ドキュメントではそれは言う:

Fieldに渡されたカスタムプロップは、入力およびメタオブジェクトと同じレベルのプロップオブジェクトにマージされます。

しかし、カスタムコンポーネントをフィールドコンポーネントに渡すと、コンパイルエラーがスローされます。

<Field
    name="E-Mail"
    component={MaterialTextField}
    myProp="Test"
/>

プロパティ 'myProp'はタイプ '(IntrinsicAttributes&IntrinsicClassAttributes>&...に存在しません.

Props属性の内部では、プレースホルダーやタイプなどの定義済みのプロパティセットのみを追加できます。別の小道具を渡すと、このエラーがスローされます。

<Field
    name="E-Mail"
    component={MaterialTextField}
    props = {{
        myProps: 'Test'
    }}
/>

タイプ '{name: "E-Mail";コンポーネント:(プロパティ:任意)=>要素;小道具:{myProps:文字列; }; } 'はタイプ'(IntrinsicAttributes&...

TypeScriptのフィールドコンポーネントにカスタムプロップを渡す可能性はありますか?

16
Deutro

私の側でさらに実験を重ねた後、カスタム小道具を渡すための解決策を見つけました:

<Field 
    name="myName"
    props={{
        type: 'text'
    }}
    component={myComponent}
    {...{
        myCustomProps1: 'myCustomProp1',
        myCustomProps2: 'myCustomProp2'
    }}
/>

MyComponentでは、プロパティのルートレベルにカスタムプロップがあります。

const myComponent = (props) => {
    return <div>{props.myCustomProp1 + " " props.myCustomProp2}</div>
}
16
Deutro

カスタムプロップReduxフォームFieldコンポーネントに渡すには、渡すすべてのプロップインターフェースを宣言する必要があります。

interface YourCustomProps {
    myProp1: string;
    myProp2: number;
}

ここで、ReduxフォームGenericFieldを使用して、FieldYourCustomFieldとして、YourCustomPropsを渡すことができるようにします。

import { Field, GenericField } from 'redux-form';

const YourCustomField = Field as new () => GenericField<YourCustomProps>;

これで、インターフェイスで宣言されているように、カスタムプロパティYourCustomFieldに渡すことができます。

<YourCustomField
    myProp1="Hi"
    myProp2={123}
    component={MaterialTextField}
/>

このように、カスタムプロップとして何でも渡すことができます。 :)

1
Vinay Sharma

私はTypeScriptユーザーではないので、型定義がどのように機能するかはわかりませんが、 Redux-form v6の型定義に関するこのスレッド を見つけました。最後に、それらは this repository にリンクしています。これは(正しく理解していれば)更新された型定義があるはずです。

別の方法としては、この特定の機能をバニラJSに切り替えることが考えられます。または、カスタムプロップを受け取り、Reduxフォームプロップを取り、それらをマージする準備ができたコンポーネントを返す関数を定義することもできます。

Edit:以下のインクルードコードで、最後の提案、いわゆるHOC(Higher Order Component)の基本的な考え方を説明しようとしました。

const inputWithCustomFields = (customFields) => ComponentToGetExtraFields => (props) => {
        const mergedProps = {...props, ...customFields};
        return (<ComponentToGetExtraFields {...mergedProps} />);
};

const ComponentThatNeedsCustomStuff = ({myCustomField1, myCustomField2, ...rest}) => {
        console.log('doing stuff with the custom props',myCustomField1, myCustomField2);
        return (<div><h1>{myCustomField1 + myCustomField2}</h1><input {...rest} /></div>);
}

const Parent = () => {
  const myCustomFields = {
     myCustomField1: "Hello, ", 
     myCustomField2: "world!", 
     value: 'can\'t change me',
     onChange: () => { /* do nothing */ }
   };
  const MergedComponent  = inputWithCustomFields(myCustomFields)(ComponentThatNeedsCustomStuff);
  return (<div>
      <MergedComponent />
    </div>);
};

ReactDOM.render(<Parent />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
0
jonahe