21
votes

I want to pass custom properties to my Redux-Form-Field. In the documentation it says:

Any custom props passed to Field will be merged into the props object on the same level as the input and meta objects.

But passing a custom prop to the Field component will throw a compile error:

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

Property 'myProp' does not exist on type '(IntrinsicAttributes & IntrinsicClassAttributes> & ...

Inside the props attribute I can only add a predefined set of properties like placeholder or type. Passing another prop will throw this error:

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

Type '{ name: "E-Mail"; component: (props: any) => Element; props: { myProps: string; }; }' is not assignable to type '(IntrinsicAttributes & ...

Is there a possibility to pass custom props to the Field component in TypeScript?

3
you have redux-form and react-redux-form but those are actually two different frameworks. Which one are you referring to? - Mario F
My bad, I am referring to redux-form. - Deutro

3 Answers

18
votes

After some more experimenting on my side I found a solution to pass custom props:

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

In myComponent you have your custom props on the root level of your properties:

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

To pass custom props to Field component of Redux Form, you need to declare an interface of all the props you want to pass.

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

Now, use GenericField from Redux Form to make Field as YourCustomField to which you will be able to pass YourCustomProps

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

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

Now you can pass custom props to YourCustomField as declared in the interface.

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

This way you can pass anything as custom props such as react components as well! :)

0
votes

I'm not a Typescript user, so I'm not sure how the type definitions work, but I found this thread about type definitions for Redux-form v6. In the end they link to this repository which is supposed to have (if I understand it correctly) updated type definitions.

I guess an alternative would be to switch to vanilla JS for this specific functionality. Or maybe it would be possible to define a function that takes your custom prop and then returns a component ready to take the Redux form props and merge them.

Edit: I've tried to illustrate the basic idea of the last suggestion, a so-called HOC (Higher Order Component), in the included code below.

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>