I have a saveMember(member: Member) method in my Action Creator. I should pass a Member type object to that method. I was able to do this with a normal HTML form. Then I tried to do it with redux-form library.
I don't understand how to use both Connect and Redux Forms in the same component. When using the normal HTML forms, I was able to define a onSubmit handler method inside the MemberForm component itself and get the values from the inputs and call the saveMember action. But I don't understand how to do it now.
Referring to some code on github I tried the following code:
import * as React from 'react';
import { Link, RouteComponentProps } from 'react-router-dom';
import { connect } from 'react-redux';
import { ApplicationState } from '../store';
import * as MembersState from '../store/Members';
import * as ReactDOM from 'react-dom';
import { Member } from "../store/Members";
import { reduxForm, Field, FormErrors, FormProps } from 'redux-form';
interface FormData {
name?: string;
age?: string;
}
const validate = (values: Readonly<FormData>): FormErrors<FormData> => {
const errors: FormErrors<FormData> = {};
if(values.name === undefined) {
errors.name = 'name needed';
}
if(values.age === undefined) {
errors.age = 'age needed';
}
return errors;
};
// At runtime, Redux will merge together...
type MemberFormProps =
MembersState.MembersState // ... state we've requested from the Redux store
& typeof MembersState.actionCreators // ... plus action creators we've requested
& RouteComponentProps<{}>; // ... plus incoming routing parameters
class MemberForm extends React.Component<MemberFormProps, {}> {
componentWillMount() {
// This method runs when the component is first added to the page
this.props.getMembers();
}
public render() {
return <div>
<h1>Members</h1>
{this.renderForecastsTable()}
<hr/>
{this.renderForm()}
</div>;
}
private renderForecastsTable() {
return <table className='table'>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody>
{this.props.members.map(member =>
<tr key={member.id}>
<td>{member.id}</td>
<td>{member.name}</td>
<td>{member.age}</td>
</tr>
)}
</tbody>
</table>;
}
private renderForm() {
return <form className="htmlForm-horizontal">
<div className="form-group">
<label className="control-label col-sm-2" htmlFor="name">Name:</label>
<Field placeholder="First name" name="name" component="input" />
</div>
<br/><br/>
<div className="form-group">
<label className="control-label col-sm-2" htmlFor="age">Age:</label>
<Field placeholder="Age" name="age" component="input" />
</div>
<br/><br/>
<div className="form-group">
<div className="col-sm-offset-2 col-sm-10">
<button type="submit" className="btn btn-default">Submit</button>
</div>
</div>
</form>;
}
}
let MemberFormConnect = connect(
(state: ApplicationState) => state.members, // Selects which state properties are merged into the component's props
MembersState.actionCreators // Selects which action creators are merged into the component's props
)
(MemberForm) as typeof MemberForm;
export default reduxForm<MemberFormProps, MemberForm>({
form: 'SelectionWithForm',
validate: validate,
onSubmit: (values, dispatch, props) => {
console.log('submit is being handled...');
let member: Member = { name: values.name, age: parseInt(values.age) };
props.saveMember(member);
}
})(MemberFormConnect);
When I use this code I get compilations errors in every line inside export default reduxForm.
ERROR in [at-loader] ./ClientApp/components/MemberForm.tsx:103:55
TS2345: Argument of type '{ form: string; validate: (values: Readonly<FormData>) => FormErrors<FormData, void>; onSubmit: (...' is not assignable to parameter of type 'Partial<ConfigProps<MemberFormProps, MemberForm>>'.
Types of property 'validate' are incompatible.
Type '(values: Readonly<FormData>) => FormErrors<FormData, void>' is not assignable to type '((values: MemberFormProps, props: MemberForm & InjectedFormProps<MemberFormProps, MemberForm>) =>...'.
Type '(values: Readonly<FormData>) => FormErrors<FormData, void>' is not assignable to type '(values: MemberFormProps, props: MemberForm & InjectedFormProps<MemberFormProps, MemberForm>) => ...'.
Type 'FormErrors<FormData, void>' has no properties in common with type 'FormErrors<MemberFormProps, void>'.
I don't have experience with react and redux, please help me.