I am using storybook to visualize changes to React components after simulating user interaction with enzyme. As a small example, I want a story displaying a component after one of its button has been clicked.
The issue I'm having is the component's constructor gets called twice: once when the component is mounted by enzyme and then after when storybook displays the component. This puts the component back to its default state so any changes following the simulated user interactions are lost.
Here's some code showing the issue. After the story loads, the button component is in the "unclicked" state, even though a click was simulated with enzyme:
import React from 'react';
class SampleComponent extends React.Component {
constructor(props){
super(props);
console.log('constructor');
this.state = {isClicked: false};
this.onClick = this.onClick.bind(this);
}
onClick(){
console.log('onClick');
this.setState({isClicked: true});
}
render(){
const text = (this.state.isClicked)? 'Clicked!' : 'Not Clicked';
return (
<div>
<input type='button' value='Click' onClick={this.onClick} />
<p>{text}</p>
</div>
);
}
}
export default SampleComponent;
The story file:
import React from 'react';
import { storiesOf } from '@storybook/react';
import { mount } from 'enzyme';
import { specs, describe, it } from 'storybook-addon-specifications';
import SampleComponent from '../src/SampleComponent';
storiesOf('SampleComponent', module)
.add('clicked', () => {
const comp = <SampleComponent/>;
specs(() => describe('clicked', function () {
it('Should display clicked state message', function () {
const output = mount(comp);
output.find('input').simulate('click');
});
}));
return comp;
});
The output to console would be:
constructor
onClick
constructor
You need to get back the underlying component instance. This will do what you want:
storiesOf('SampleComponent', module)
.add('clicked', () => {
let output;
specs(() => describe('clicked', function () {
it('Should display clicked state message', function () {
output = mount(<SampleComponent />);
output.find('input').simulate('click');
});
}));
const Inst = () => output.instance();
return <Inst />
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With