recompose
recompose copied to clipboard
Any plans for the new context API?
Is there already some work done to support the upcoming context API?
It makes use of render props so I don't know how well will it fit with recompose, is this even going to be take in consideration?
lets discuss :-)
I'm far from an expert of HOCs, I think it's feasible, but I guess it will add 3 wrappers because of 1) the HOC, 2) the Context component, 3) the render prop
I'm not sure if this is going to be a problem.
In my mind, it would be something like:
import { createContext } from 'recompose'
const themeContext = createContext({ color: 'green' })
withContext is a HOC wrapper for the context Provider, which accepts a function mapping props to context:
themeContext.withContext(props => ({ color: props.color }))
getContext is a HOC wrapper for the context Consumer (or we can rename it to consumeContext):
themeContext.getContext
Awesome @wuct . From my side I would like to add to getContext above an optional map function, so we could rename context variables. Also I think that recompose createContext can also return default React consumer and provider.
Looks good to me :)
Hi all, you may be interested in this. I have just published a npm package -- https://github.com/SunHuawei/with-context. I think it is the easiest way to use the new context API. Please try it and give me some feedback, really appreciate your attention.
@SunHuawei the string key here might be a pain in type systems.
@SunHuawei looks solid upon cursory glance. I wish that this was just how context worked in recompose
@wuct , thanks for your kind reminder. I'm not not sure what is the type systems you mentioned, the type system like flow/typescript, or PropTypes? However, any suggestion for that? I must have something to learn, honestly, could you show me the path?
Using string keys means you can't determine what props will be pass to the base component until runtime, so you can't type the HOC with Flow/TypeScript. To avoid this problem, you can use a function instead. You can compare how we type withStateHandlers and withState in flow to get an idea.
@wuct , thanks a lot. I think I have much things to learn.
@wuct Looking at your proposal maybe these names would be most obvious? I don't feel like "with" is always the most intuitive naming convention.
Just thinking out loud...
createContext
provideContext
consumeContext
Just few cents. about @wuct proposal
withContext(props => ({ color: props.color })) - can be a problem as every render this produces a new object, and having that context uses reference identity to determine when to re-render it will cause all the consumers to rerender. We can avoid this using current HOCs but should think about how to decrease amount of code needed.
Avoiding rerenders using current HOCs
withPropsOnChange(['color'], ({ color }) => ({ newContext: { color } }) ),
withContext(({ newContext }) => newContext)
One of ideas is to combine both above into one withContextOnPropsChange ;-)
OR just use shallow equality of newly created object in withContext and if it is equally shallow to previous - return previous. So proposed API will stay the same but equality check will be more relaxed vs react.
The main helper that I've been using all the time with new context is mapContextToProps, I think that is probably the 90% usecase for a context helper, something that takes in a Consumer (or array of consumers) and produces an HOC that passing those values as props (as determined by mapToProps) function.
How about separating the logic of createContext into two HOCs?
The Consumer part is a general HOC withConsumerProps which is similar to withProps.
It would be more flexible for two Render props case:
import { withConsumerProps } from 'recompose';
const { Consumer: I18NConsumer } = React.createContext({ i18n: 'en' });
const enhance = compose(
// Context (Function as Child Components)
withConsumerProps(ThemeConsumer, ({ theme }) => ({ theme })),
withConsumerProps(I18NConsumer, ({ i18n }) => ({ i18n })),
// Render props
withConsumerProps(Item, ({ value }) => ({ value }), 'render'),
);
demo: https://codesandbox.io/s/znn65pknlx?expanddevtools=1
@evenchange4 What withConsumerProps does is converting any render-props component to a HOC and is not specific to a context consumer. Because we already have withRenderProps, which convert a HOC to a render-props component, it makes sense to have another function which converting a render-props component to a HOC. I propose we rename withConsumerProps to a more generalized name, maybe fromRenderProps (whichs siganature is RenderPropsComponent -> HOC), and provide another HOC for consuming context specifically, which can use fromRenderProps internally.
I agree with @wuct. Ideally we want to be able to continue using compose with context consumers
const SomeComponent = compose(
withRouter,
fromRenderProps(ThemeContext.Consumer),
)(SomeButton);
Are there any news about this ?
don't expect any new features
https://github.com/acdlite/recompose#a-note-from-the-author-acdlite-oct-25-2018
I think fromRenderProps should be usable for handling context.
That said the lack of attention paid to the new context system is really disappointing. Especially given the fact that the new context API has been around for awhile + hooks have not even been released in a stable version yet + even after release hooks are severely crippled in regards to context usage until we fix facebook/react#14110.
Just need time to implement it. A pull request is welcome.
For those that found this thread and want something now, here's a pretty simple implementation using Hooks. It would obviously need a better provider HOC but I'm already slamming so many providers into my apps these days with nest(....) I don't particularly care.
https://codesandbox.io/s/recompose-hoc-new-context-jqjbz
Is it dead? ((
Yes, have a look at README