Skip to content

Commit 5917781

Browse files
committed
feat: add <State> component
1 parent 6abb773 commit 5917781

File tree

3 files changed

+129
-0
lines changed

3 files changed

+129
-0
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import {createElement as h} from 'react';
2+
import {renderToStaticMarkup} from 'react-dom/server';
3+
import {expect} from 'chai';
4+
import {State} from '..';
5+
6+
describe('<State> SSR', () => {
7+
it('renders without crashing with the expected value', () => {
8+
const html = renderToStaticMarkup(h(State, {
9+
init: {
10+
foo: 'bar'
11+
},
12+
render: ({foo}) => <div>{foo}</div>
13+
}));
14+
15+
expect(html).to.equal('<div>bar</div>');
16+
});
17+
});

src/State/__tests__/index.test.tsx

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import {h} from '../../util';
2+
import {mount} from 'enzyme';
3+
import {State} from '..';
4+
5+
describe('<State>', () => {
6+
it('is a component', () => {
7+
expect(State).toBeInstanceOf(Function);
8+
});
9+
10+
it('can set initial state object', () => {
11+
const wrapper = mount(h(State, {
12+
init: {
13+
foo: 'bar',
14+
baz: 'bazoooka'
15+
}
16+
}, (state) => {
17+
expect(state).toEqual({
18+
foo: 'bar',
19+
baz: 'bazoooka'
20+
});
21+
22+
expect(() => {
23+
expect(state).toEqual({
24+
foo: 'bar',
25+
});
26+
}).toThrow();
27+
28+
return null;
29+
}));
30+
});
31+
32+
it('uses render prop', () => {
33+
const wrapper = mount(h(State, {
34+
init: {
35+
foo: 'bar',
36+
baz: 'bazoooka'
37+
},
38+
render: (state) => {
39+
expect(state).toEqual({
40+
foo: 'bar',
41+
baz: 'bazoooka'
42+
});
43+
44+
expect(() => {
45+
expect(state).toEqual({
46+
foo: 'bar',
47+
});
48+
}).toThrow();
49+
50+
return null;
51+
}
52+
}));
53+
});
54+
55+
describe('setState()', () => {
56+
it('can change state', () => {
57+
const foos = [];
58+
let setState;
59+
60+
const wrapper = mount(<State
61+
init={{
62+
foo: 'bar'
63+
}}
64+
render={({foo}, set) => {
65+
foos.push(foo);
66+
setState = set;
67+
68+
return null;
69+
}}
70+
/>);
71+
72+
setState({
73+
foo: 'baz'
74+
});
75+
76+
expect(foos).toEqual(['bar', 'baz']);
77+
})
78+
});
79+
});

src/State/index.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import {Component} from 'react';
2+
import {noop} from '../util';
3+
import renderProp from '../util/renderProp';
4+
5+
export interface IStateProps {
6+
children?: (state: IStateState, setState?) => React.ReactElement<any>;
7+
init: object,
8+
onChange?: (state: any) => void;
9+
render?: (state: any, setState?) => void;
10+
}
11+
12+
export interface IStateState {
13+
14+
}
15+
16+
export class State extends Component<IStateProps, IStateState> {
17+
static defaultProps = {
18+
onChange: noop
19+
};
20+
21+
state: IStateState;
22+
23+
constructor (props, context) {
24+
super(props, context);
25+
26+
this.state = props.init;
27+
this.setState = this.setState.bind(this);
28+
}
29+
30+
render () {
31+
return renderProp(this.props, this.state, this.setState);
32+
}
33+
}

0 commit comments

Comments
 (0)