recompose icon indicating copy to clipboard operation
recompose copied to clipboard

Any plans for the new context API?

Open FezVrasta opened this issue 7 years ago • 24 comments

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?

FezVrasta avatar Feb 12 '18 15:02 FezVrasta

lets discuss :-)

istarkov avatar Feb 12 '18 17:02 istarkov

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.

FezVrasta avatar Feb 12 '18 17:02 FezVrasta

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

wuct avatar Feb 16 '18 06:02 wuct

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.

istarkov avatar Feb 16 '18 07:02 istarkov

Looks good to me :)

wuct avatar Feb 19 '18 21:02 wuct

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 avatar Feb 28 '18 11:02 SunHuawei

@SunHuawei the string key here might be a pain in type systems.

wuct avatar Mar 04 '18 06:03 wuct

@SunHuawei looks solid upon cursory glance. I wish that this was just how context worked in recompose

elmarsto avatar Mar 21 '18 21:03 elmarsto

@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?

SunHuawei avatar Mar 26 '18 05:03 SunHuawei

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 avatar Mar 26 '18 14:03 wuct

@wuct , thanks a lot. I think I have much things to learn.

SunHuawei avatar Mar 28 '18 07:03 SunHuawei

@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

GollyJer avatar Mar 30 '18 03:03 GollyJer

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.

istarkov avatar Mar 30 '18 09:03 istarkov

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.

jquense avatar May 10 '18 13:05 jquense

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 avatar May 23 '18 07:05 evenchange4

@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.

wuct avatar May 24 '18 06:05 wuct

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);

xzyfer avatar Jun 06 '18 10:06 xzyfer

Are there any news about this ?

udielenberg avatar Jan 05 '19 00:01 udielenberg

don't expect any new features

https://github.com/acdlite/recompose#a-note-from-the-author-acdlite-oct-25-2018

barbalex avatar Jan 05 '19 03:01 barbalex

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.

dantman avatar Jan 05 '19 03:01 dantman

Just need time to implement it. A pull request is welcome.

wuct avatar Jan 20 '19 08:01 wuct

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

pckilgore avatar Sep 11 '19 16:09 pckilgore

Is it dead? ((

PredokMiF avatar Aug 12 '21 22:08 PredokMiF

Yes, have a look at README

ipanasenko avatar Aug 12 '21 22:08 ipanasenko