Skip to content

Commit 758daa8

Browse files
committed
feat: Add transformContext HoC
1 parent 0dda4d3 commit 758daa8

File tree

4 files changed

+75
-2
lines changed

4 files changed

+75
-2
lines changed

src/forwardRef.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import React from 'react';
2+
3+
export default function forwardRef(
4+
renderFn,
5+
{ displayName, propTypes, defaultProps },
6+
) {
7+
const render = (...args) => renderFn(...args);
8+
9+
Object.assign(render, { displayName, propTypes, defaultProps });
10+
return React.forwardRef(render);
11+
}

src/mapContextToProps.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from 'react';
2+
import forwardRef from './forwardRef';
23

34
const getDisplayName = Component => {
45
const name =
@@ -47,9 +48,10 @@ function $mapContextToProps(
4748
}
4849

4950
const contextTransform = consumers.length === 1 ? singleRender : multiRender;
50-
contextTransform.displayName = displayName || getDisplayName(Component);
5151

52-
return React.forwardRef(contextTransform);
52+
return forwardRef(contextTransform, {
53+
displayName: displayName || getDisplayName(Component),
54+
});
5355
}
5456

5557
export default function mapContextToProps(maybeOpts, mapToProps, Component) {

src/transformContext.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React from 'react';
2+
import forwardRef from './forwardRef';
3+
4+
export default function transformContext(Context) {
5+
return forwardRef(
6+
props => (
7+
<Context.Consumer>
8+
{context => (
9+
<Context.Provider value={props.mapToValue(context)}>
10+
{props.children}
11+
</Context.Provider>
12+
)}
13+
</Context.Consumer>
14+
),
15+
{ displayName: `ContextTransformer` },
16+
);
17+
}

test/transformContext.test.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React from 'react';
2+
import { mount } from 'enzyme';
3+
4+
import transformContext from '../src/transformContext';
5+
6+
describe('transformContext', () => {
7+
it('should transform a context value', () => {
8+
const Context = React.createContext('foo');
9+
const Transformer = transformContext(Context);
10+
11+
const mapper = jest.fn(value => (value === 'foo' ? value : 'baz'));
12+
13+
function Inner() {
14+
return <Context.Consumer>{v => <div>{v}</div>}</Context.Consumer>;
15+
}
16+
function Wrapper() {
17+
return (
18+
<Transformer mapToValue={mapper}>
19+
<Inner />
20+
</Transformer>
21+
);
22+
}
23+
24+
function Nested() {
25+
return (
26+
<Context.Provider value="quack">
27+
<Wrapper />
28+
</Context.Provider>
29+
);
30+
}
31+
expect(
32+
mount(<Wrapper />)
33+
.find('div')
34+
.text(),
35+
).toEqual('foo');
36+
37+
expect(
38+
mount(<Nested />)
39+
.find('div')
40+
.text(),
41+
).toEqual('baz');
42+
});
43+
});

0 commit comments

Comments
 (0)