Reputation: 625
I have a functional component that required props height
and width
to be rendered. Let's call it PureSizableDiv
:
const PureSizableDiv = ({ height, width }) =>
<div style={{ height, width }}>I'm a div!</div>
I also have a React context called Size
:
import React from 'react';
import { compose, fromRenderProps } from 'recompose';
export const { SizeProvider, SizeConsumer } = React.createContext({
height: null,
width: null,
});
Instead of manually creating a new HoC like this:
export const withSize = Component => (props) =>
<SizeConsumer>
{
({ height, width }) =>
<Component
height={height}
width={width}
{...props}
/>
}
</SizeConsumer>;
I'd like to know if there's a shorter a cleaner way using recompose
to do this.
I tried
export const withSize = compose(
fromRenderProps(SizeConsumer, ({ height, width }) => ({ height, width })),
);
But got the error Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Upvotes: 2
Views: 1435
Reputation: 625
I had connected my component, but I wasn't using properly the Context API.
I fixed the code and it worked flawlessly using fromRenderProps
from recompose
.
Working code:
import React from 'react';
import { compose, fromRenderProps } from 'recompose';
const PureSizableDiv = ({ height, width }) =>
<div style={{ height, width }}>I am a div!</div>;
const SizeContext = React.createContext({
height: null,
width: null,
});
const withSize = compose(
fromRenderProps(SizeContext.Consumer, ({ height, width }) => ({ height, width })),
);
// Usage
const Wrapper = ({ children, height, width }) =>
<SizeContext.Provider
value={{
height: height,
width: width,
}}
>
{children}
</SizeContext.Provider>;
const SizedDiv = withSize(PureSizableDiv);
// Render components
<Wrapper>
<SizedDiv/>
</Wrapper>
Upvotes: 4
Reputation: 85545
You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
The error is appearing it's because you're not exporting the Component with the compose:
export const withSize = compose(
fromRenderProps(SizeConsumer, ({ height, width }) => ({ height, width })),
)(Component);
// ^^
Upvotes: 2