# Extracting values from refs pointing to form inputs

I have a form component with multiple refs pointing to form inputs. On submit, those inputs' values need to be passed the into form callback, structured as an object.

Currently, it's achieved like this:

class MyComponent extends React.Component {
render() {
return (
<form onSubmit={() => this.onSubmit()}>
<input ref="firstName">
<input ref="lastName">
<input ref="age">
<input ref="sex">
</form>
);
}
onSubmit() {
let firstName = this.refs.firstName.value.trim();
let lastName = this.refs.lastName.value.trim();
let age = this.refs.age.value.trim();
let sex = this.refs.sex.value.trim();

this.props.onSubmit({
firstName,
lastName,
age,
sex
});
}
}


These lines let firstName = this.refs.firstName.value.trim(); look like a code duplication to me. Could they be rewritten into something more elegant? ES2015 answers are welcome.

• Please replace those hypothetical names with the real names, otherwise this question may be off-topic. – Jamal Feb 2 '16 at 20:30

These lines let firstName = this.refs.firstName.value.trim(); look like a code duplication to me. Could they be rewritten into something more elegant?

Looks ok to me. These fields are too few to be generalized by some generalization logic.

Now if the form does grow, you can just get a reference to the <form> and do a quick querySelectorAll for all input elements, including select and textarea that have a name.

var inputs = this.refs.form.querySelectorAll('input[name]');


You can then loop through them, get the name and value and use it as key and value for your object. For simple cases, this works. A slightly more complicated case is handling complex names like foo[a] and foo[b] which is usually interpreted as {foo: {a : 'value', b: 'value'}}.

Functional programming to the rescue! With a help of Ramda, onSumbit can be rewritten as follows:

onSubmit() {
const personOf = pipe(
pick(['firstName', 'lastName', 'age', 'sex']),
map(pipe(
prop('value'),
trim
))
);

this.props.onSubmit(personOf(this.refs));
}