One thing to keep in mind is that arrow functions are not added to the class prototype, so if you…
Christopher Burbank
32

Here’s a situation where I had to use the binding technique in componentWillMount.

import React, { Component } from ‘react’;
class Register extends Component {
state = {
firstName: ‘’,
lastName: ‘’,
phoneNumber: ‘’
};
componentWillMount() {
this.submitData = this.submitData.bind(this);
this.validate = this.validate.bind(this);
}
_validName = () => {
if (this.state.firstName.length < 3 || this.state.lastName.length < 3) return false;
return true;
}
_validPhone = () => {
var re = /\(?([0–9]{3})\)?([ .-]?)([0–9]{3})\2([0–9]{4})/;
return re.test(this.state.phoneNumber);
};
validate () {
if (!this._validName() || !this._validPhone()) return false;
return true;
};
submitData () {
if (this.validate()) {
//
}
}
render() {
return (
<div className=”Register”>
<h1 className=”title”>Phone Pay</h1>
<form onSubmit={this.submitData} id=”namePhoneNumberForm” name=”namePhoneNumberForm”>
<input id=”firstname-field” className=”text-input” type=”text” name=”first-name” placeholder=”First Name” />
<input id=”lastname-field” className=”text-input” type=”text” name=”last-name” placeholder=”Last Name” />
<input id=”phonenumber-field” className=”text-input” type=”text” name=”phonenumber” placeholder=”Phone Number” />
<input id=”submit-btn” type=”submit” value=”Next” name=”submit” />
</form>
</div>
);
}
}
export default Register;

This is a simple component that should perform validation when the submits the form.

import React from ‘react’;
import ReactDOM from ‘react-dom’;
import sinon from ‘sinon’;
import Enzyme, { shallow, mount } from ‘enzyme’;

import Adapter from ‘enzyme-adapter-react-16’;
Enzyme.configure({ adapter: new Adapter() });
import Register from ‘./Register’;
describe(‘Register component’, ()=> {
let div, regComp;
beforeEach(() => {
div = document.createElement(‘div’);
regComp = ReactDOM.render(<Register />, div);
});
it(‘Renders without crashing’, () => {
const div = document.createElement(‘div’);
ReactDOM.render(<Register />, div);
ReactDOM.unmountComponentAtNode(div);
});
it(‘Validate name’, () => {
regComp.setState({
firstName: ‘victor’,
lastName: ‘Nwaokocha’
});
const validEntry = regComp._validName();
expect(validEntry).toBe(true);
});
it(‘Validate phone number’, () => {
regComp.setState({
phoneNumber: ‘09098612833’
});
const validEntry = regComp._validPhone();
expect(validEntry).toBe(true);
});
it(‘Execute sumbitData method when form is submitted’, () => {
sinon.spy(Register.prototype, ‘submitData’);
const wrapper = mount(<Register />);
wrapper.find(‘#namePhoneNumberForm’).simulate(‘submit’);
expect(Register.prototype.submitData.calledOnce).toBe(true);
});
it(‘Execute validate method when form is submitted’, () => {
sinon.spy(Register.prototype, ‘validate’);
const wrapper = mount(<Register />);
wrapper.find(‘#namePhoneNumberForm’).simulate(‘submit’);
expect(Register.prototype.validate.calledOnce).toBe(true);
});
});

Apparently, the last two would fail if I had not binded them to this in componentWillMount or used .bindin the onSubmit of form tag, as mentioned by Adrian Kaczmarek

However, using arrow functions to define both submitData and validate method like this:

validate = () => {
if (!this._validName() || !this._validPhone()) return false;
return true;
};
submitData = () => {
if (this.validate()) {
//
}
}

would make both sinon.spy(Register.prototype, ‘submitData’); and sinon.spy(Register.prototype, ‘validate’); throw a

TypeError:

TypeError: Attempted to wrap undefined property submitData as function

TypeError: Attempted to wrap undefined property validate as function

Why?

This because when the Register class gets transpiled it would look like this

function Register () {
this.submitData = function () {};
this.validate = function () {};
};

In essence both methods are not exposed and they can only be tested when the Register function is used in form of constructor, for example:

let reg = new Register();

Hence, Register.prototype.submitData and Register.prototype.validate would return undefined when we try to access them.

Like what you read? Give Victor Le Nerd a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.