Reputation: 1167
I've got simple form component in react-native app. I use Type Script. In my component I have few initialized fields and two connected actions. In the end I create form and then connect actions and my store. Unfortunately this combination doesn't work. I receive an error You must pass a component to the function returned by connect. Instead received {"displayName":"ReduxForm","defaultProps":{...,"form":"ProfileScreen"}}
.
When I check the type of form returned by function reduxForm I receive object
instead of function
and this is why connect
refuses to accept it.
My code looks as follows:
import * as React from 'react';
import I18n from 'ex-react-native-i18n'
import {KeyboardAvoidingView, ScrollView, View, ViewStyle} from 'react-native';
import {connect} from 'react-redux';
import {Field, InjectedFormProps, reduxForm} from 'redux-form';
import {Card, CardSection, FormField} from '../components/common';
import {CustomButton} from "../components/CustomButton";
import {Profile, VendorProfile} from "../store/Profile";
import {Store} from "../store/Store";
import {Colors} from "../constants/Colors";
import {FetchProfileFields, fetchProfileFields, saveProfile, SaveProfile} from "../actions/profile/ProfileActions";
import {
maxLength20,
maxLength40,
maxLength5,
maxLength7,
maxLength70,
minLength3,
minLength5,
phoneNumber,
required,
zipCode
} from "../actions/validations";
import {normalizePhone, normalizeZipCode} from "../actions/normalizations";
interface Props {
fetchProfileFields: FetchProfileFields
saveProfile: SaveProfile
profile: Profile
}
type FormProps = VendorProfile;
class ProfileScreen extends React.Component<InjectedFormProps<FormProps, Props> & Props> {
componentDidMount() {
this.props.fetchProfileFields();
};
render() {
const {handleSubmit, pristine, reset} = this.props;
return (
<KeyboardAvoidingView behavior="padding" keyboardVerticalOffset={75} style={{flex: 1}}>
<ScrollView keyboardShouldPersistTaps='always'>
<Card style={{marginBottom: 20}}>
<CardSection round>
<Field name="name" validate={[required, minLength5, maxLength40]} component={this.renderField}/>
<Field name="companyName" validate={[required, minLength3]} component={this.renderField}/>
<Field name="phoneNumber" validate={phoneNumber} normalize={normalizePhone} component={this.renderField}/>
<Field name="locality" validate={maxLength20} component={this.renderField}/>
<Field name="zipCode" validate={zipCode} normalize={normalizeZipCode} component={this.renderField}/>
<Field name="street" validate={maxLength70} component={this.renderField}/>
<Field name="streetNumber" validate={maxLength7} component={this.renderField}/>
<Field name="flatNumber" validate={maxLength5} component={this.renderField}/>
</CardSection>
</Card>
</ScrollView>
<View style={styles.buttonsContainer}>
<CustomButton title={I18n.t('profileScreen.revertChangesButton')}
icon="undo"
onPress={reset}
disabled={!pristine}
/>
<CustomButton title={I18n.t('profileScreen.saveChangesButton')}
icon="save"
onPress={handleSubmit(this.onSubmit)}
/>
</View>
</KeyboardAvoidingView>
);
}
private renderField = (formProps: any) => {
const name = formProps.input.name;
const {valid, error} = formProps.meta;
return (
<FormField
label={I18n.t(`profileScreen.${name}`)}
value={formProps.input.value}
onChangeText={formProps.input.onChange}
error={error}
invalid={!valid}
/>
);
};
private onSubmit = (formProps: FormProps) =>
this.props.saveProfile(formProps);
}
const styles = {
buttonsContainer: {
borderTopWidth: 1,
borderTopColor: Colors.dark,
flexDirection: 'row',
justifyContent: 'center',
marginBottom: 5,
paddingTop: 5
} as ViewStyle,
};
const form = reduxForm<FormProps, Props>({form: 'ProfileScreen', enableReinitialize: true})(ProfileScreen);
console.log(typeof form); // 'object' here instead of 'function'
const mapStateToProps = ({profile}: Store) => ({initialValues: profile.fields, profile});
const mapDispatchToProps = {fetchProfileFields, saveProfile};
export default connect(mapStateToProps, mapDispatchToProps)(form);
The versions of libraries I use are:
"react-redux": "^5.0.7",
"redux": "^3.7.2",
"redux-form": "^8.1.0",
"@types/react-redux": "^6.0.9",
"@types/redux-form": "^7.4.15"
Any ideas what causes this problem? When I use only connect
or only reduxForm
they work. How do I investigate it further?
Upvotes: 3
Views: 441
Reputation: 3203
It's still broken with the latest good dependencies:
"react": "16.5.0",
"react-redux": "5.0.7",
"redux": "4.0.1",
"redux-form": "8.2.2",
I got around it by doing:
export default connect(
mapStateToProps,
mapDispatchToProps,
)((props) => <form {...props} />);
Upvotes: 0
Reputation: 1167
I updated redux and redux-form and it works now
"react-redux": "^6.0.1",
"redux": "^4.0.1",
"redux-form": "^8.1.0",
"@types/react-redux": "^7.0.1",
"@types/redux-form": "^7.4.15",
Upvotes: 2