-
Notifications
You must be signed in to change notification settings - Fork 558
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New version of context #2
Conversation
A proposal for a new version of context addressing existing limitations.
@mjackson |
@jaredpalmer What's the use case for |
@jaredpalmer Yep. === is the default. @acdlite There's a difference between discouraging mutability and making it impossible to use, IMO. Seems like exactly what |
@mjackson Mutation is not impossible with this proposal, it's just slightly less convenient. You can mutate one level down, just not the outermost container. Same as |
Just giving an escape hatch to fallback to. I can see why this should be discouraged. However, mutation did come up in Formik the other day where I wanted to alter something within context if a certain declarative component existed in the subtree. Edit: Ahh I see now that you can mutate one level down |
Historically we have tried to be as forgiving of mutation as possible. When we introduce async rendering (this proposal is designed with async in mind), we may need to be a bit more restrictive. However, there are cases where React already privileges immutability. |
|
||
# How we teach this | ||
|
||
This would be our first API that uses render props. They are an increasingly |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"render props" and "function children" are different; no matter how they're implemented, children aren't just a normal prop - they're special (the third argument to createElement
wins over a "children" prop, for example).
Please don't encourage function children.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't encourage function children.
@ljharb Can you explain why this shouldn't be encouraged?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@paularmstrong One argument would be that children
is almost always used as an implicit prop, but children
as a function encourages using children
as an explicit prop, which will lead to a bugs when someone attempts to use both at the same time.
<Thing children={firstFn}>
woops
</Thing>
React.createElement(Thing, { children: firstFn}, 'woops')
{
type: Thing,
props: { children: 'woops' },
...
}
Yes, that can already happen, but I've never seen anyone write something like this:
<Thing
children={
<Well>
<This is='awkward' />
</Well>
}
>
...
</Thing>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, @ryanflorence convinced me that it's easier to teach people a render
prop accepts a function than it is to teach folks that the children
prop can be a function. So in my teaching and open source I've been moving things over to render
exclusively to hopefully make things more cohesive across the community while making it easier for people to pick up.
So, I'm in favor of using a prop called render
personally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I completely agree with using render
prop instead of children. In any instruction/demos I have given it is much easier for people to wrap their head around a prop called render
over children being a function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That just depends on how you format this. You don’t have to indent it an extra time.
<MyComponent>
{x => (
<div>{x}</div>
)}
</MyComponent>
That's how Prettier formats it too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By default, Prettier formats both as 1-liners 😄
<div>
<MyComponent>{x => <div>{x}</div>}</MyComponent>
<MyComponent render={x => <div>{x}</div>} />
</div>;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just my 2 cents, if we go with a render
prop we may as well drop children
all together, no reason to keep two props that serve the exact same purpose...
Just to say, please keep children
, if one prefers the explicit prop approach, they can do:
<Foo children={x => x} />
If one does:
<Foo children={x => x}>y</Foo>
I'd first ask myself what am I trying to achieve, and then think
the inner content of a component is just treated as
children
, so I'm just definingchildren
twice, where the latter will take precedence, like any other prop in React
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just want to support the part where @FezVrasta wrote "please keep children-as-func". :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
## Add displayName argument to createContext for better debugging | ||
|
||
For warnings and React DevTools, it would help if providers and consumers | ||
had a `displayName`. The question is whether it should be required. We could |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If they have a function name, they don't need a displayName - perhaps making getComponentName(…)
required, but not displayName specifically?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My original point is that with this API (unlike existing one) we don’t know which context is missing to show a meaningful warning. Passing a name (explicitly or implicitly) to createContext would solve that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Totally fair, I'm 100% fine with requiring a name - just not requiring displayName
specifically, since normal function names should be more than sufficient.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
createContext()
isn’t bound to any component or function in particular so it can’t read a .name
from it. Therefore my proposal is to make it an argument (even if optional). I think that’s what displayName
was referring to. For example:
const Theme = React.createContext('light', {
displayName: 'Theme’
});
Sorry if I’m missing your point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another option is
const Theme = React.createContext('light');
Theme.displayName = 'Theme';
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gaearon ah, I misunderstood. In that case, yes, I'd say requiring displayName makes perfect sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Static patterns like:
const Theme = React.createContext('light');
Theme.displayName = 'Theme';
can often prevent tree-shaking/dead code elimination. I'd advise not to recommend this officially, better to have an optional extra param for createContext
+ maybe auto add static displayName
with babel plugin for the development purposes.
|
||
## Other | ||
|
||
* Should the consumer use `children` as a render prop, or a named prop? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
named prop, please. children are special, and should only be nodes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for render
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
children are special, and should only be nodes.
Would you mind elaborating on this a little more?
One thought I have is that a new prop could be considered as API bloat if children
already functions exactly as it needs to. I'm not convinced one way or the other on this one, by the way; I'm just sharing one more thing worth considering.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type signature for the children prop is pretty consistent across all built-in React components (that I can think of) and most components shipped with third party libraries - Component | SFC | string | etc. The two big exceptions that I've seen are components that don't support children at all and components that require a single child component (React Router's FooRouter components spring to mind).
In particular I think the distinction between (foo) => <DomElement />
vs ({foo}) => <DomElement />
and {renderProp}
vs <FunctionalComponent />
is a fine one. I could see that getting confusing in particular if the render prop function isn't defined inline.
All that is why I prefer an explicit 'render' prop, anyway. My knowledge of the React ecosystem is not nearly as in-depth as many of yours' - are there lots of big exceptions that I'm not thinking of?
Edit to add: this is all a user's perspective, not a package author's. If you're still gonna try and discourage users from using the new Context API all of the above might be considered a plus.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense to me, @JNaftali . I’m now leaning more in favor of a separate prop as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can always pass children
as prop:
<Foo children={() => {...}} />
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ljharb Component
s have always been free to do whatever they want with children
. I would agree with you if React by design always passed through children
unaltered, but there are so many library components out there that conditionally render children, render them inside wrappers (e.g. interactive rearrangeable grids), etc. that I think "children
are special" is a dangerous argument that leads to restricting the power of React.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, saying that children should only be nodes because they are "special", or because the third argument to createElement wins over a "children" prop, are non-arguments. They don't really explain what if anything you consider cleaner, easier to read, easier to understand, less error prone, etc. about ensuring that children are only nodes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see how a convention could possibly 'restrict the power of React'. Conventions don't stop you from doing anything. They're just a tool to make it easier for other people to understand how to use the things you write. React's power is such that given any one of these APIs it'd be easy to implement any of the others that will remain true no matter which of these APIs get implemented.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's true, it's not clear to me if @ljharb is just advocating this as a convention or if he would be in favor of dropping support for function children from React.
As far as making things easier to understand...personally I find child functions more obvious than render functions in other props, but I guess I'm in the minority.
## Other | ||
|
||
* Should the consumer use `children` as a render prop, or a named prop? | ||
* How quickly should we deprecate and remove the existing context API? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
very slowly. Separately, it must be possible to write a component that can work, simultaneously, on old React (with current context) and new React (with new context).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good point about libraries needing to support both APIs at the same time
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implementation wise could we only leave the new implementation but polyfill the old API on top of it (with current broken semantics)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ooh maybe! Should at least consider it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As long as I can trivially author a package that can work in both, I consider this addressed :-)
We didn't use context that much and decided to use Redux instead. To provide some inputs, I scanned one module. If it helps:
|
To be clear even if you use Redux, React Redux still uses context under the hood. The problem is it has to reimplement a tree-aware subscription mechanism. And that won’t work very well with React async mode. The proposal is both about making context friendlier for direct use and to make it better for libraries built on top (such as React Redux). |
(Copied from previous PR) I think a life-cycle hook in regards to context changes should be discussed. Relying on a child function for detecting this isn't exactly feasible for all situations. Perhaps another prop on the consumer? <Consumer onChange={this.handleChange} /> |
@milesj brings up a good point. It took me a bit to parse his question but I think he's getting at this: what if you need the context value in any of the lifecycle hooks? The problem with a render prop API is it makes that very difficult; I've run into this problem with other render prop-based APIs as well. Take AutoSizer which gives you the width/height. I needed to do something special with the width to figure out if I should render something or not, and that logic needs to be re-run when something else changes in a lifecycle, so I need the width there. Hope that makes sense, I can't remember the details of the problem. Is the suggested pattern to pull out all the lifecycle code that needs to depend on it into a sub-component, and pass the value down as a prop to it? I think that works but seems a bit ceremonious. |
Yes, this is the main problem with render prop APIs. I think this is mostly an educational challenge, though, because there's always the option to wrap it in an HOC: function consume(Context) {
return Component => {
return function Consumer(props) {
return (
<Context.Consumer>
{context => <Component context={context} {...props} />}
</Context.Consumer>
);
}
}
} |
Usually my objection to wrapping in an HOC, versus using an HOC from the start, is it requires two extra components instead of one. But in this case, we want the extra |
Faster to scan in what case? Is that benefit enough to warrant a HOC in the default API? (Thanks for explaining!) |
Faster to scan for To be clear, we could still implement it this way with an HOC-first API. I was just rebutting my own devil's advocate point about adding extra nodes to the tree :D EDIT: Realized I misread your question. Faster to scan for |
I'm working on adding a high-level description of the implementation, will try to publish later today or tomorrow. |
Will the new API support provider nesting like we can do it today? One use case example is nested theme. |
@jlongster That's half of the question. But basically, I think the new context would need to hit these points:
|
container. (Or even just alternate between two copies.) React will detect a new | ||
object reference and trigger a change. | ||
|
||
## Only one provider type per consumer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Someone will inevitably develop a component to do this composition automatically. I'm not worried about this drawback 👌
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, and while I'm not super excited about the (below) suggested layering I'm certain that if one wasn't available I'd simply make one for use in apps to layer them together ala <ApplicationKitchenSinkConsumer>
or something like that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with you about the tooling, it will happen because it is necessary.
Inspectors, stack trace and performance may be impacted by the layering though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I honestly doubt this will happen all that often... 🤷♂️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also consider that we can change the DevTools to display this however we like
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@acdlite Indeed! DevTools improvements for HOC/layering makes sense beyond this RFC I think.
@kentcdodds I grep'ed the code of our apps this afternoon to review the impact of this RFC. We only have about 25 developers working with React, so consider my feedback with a grain of salt - we do not have the same stats as Facebook has :).
Our login button render method changes when logged or not authenticated (login or logout), on the theme (color), on being connected to the network or offline (disabled) and on the language of the user.
Overall, 20% of our context dependent render methods read 2 or more "atomic global state variable". If I understood correctly, the RFC suggests that if we want to only use React with no 3rd party tool, we should use 1 Context Consumer for each Context Providers we want to "consume from" - it sounds inconvenient to me.
But we already tooled ourselves with Redux and the RFC doesn't degrade our Redux experience so if it solves problems for others, go!
What about your React applications?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most applications don't use the context API directly in every component that needs it and instead use an abstraction of some kind (HOC, render prop, or something else) to access context. In this case, the impact of the APIs verbosity is pretty minimal and the benefits of the new API make it easily worth it.
|
||
# How we teach this | ||
|
||
This would be our first API that uses render props. They are an increasingly |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, @ryanflorence convinced me that it's easier to teach people a render
prop accepts a function than it is to teach folks that the children
prop can be a function. So in my teaching and open source I've been moving things over to render
exclusively to hopefully make things more cohesive across the community while making it easier for people to pick up.
So, I'm in favor of using a prop called render
personally.
|
||
This would be our first API that uses render props. They are an increasingly | ||
popular pattern in third-party React libraries. However, there could be learning | ||
curve for beginners. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't deny the learning curve. But to be fair, there's a learning curve (and arguably a steeper one) with the current context API. In addition, I think people will start to see render
prop APIs before they have to start using context themselves. So it's unlikely that people will come to the context API before they've experienced a similar API with other libraries first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed with @kentcdodds, context has a learning curve. I think beginners coming across the proposed context API, making use of a render
prop, will have a much easier time grokking what is happening, or where to start with it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The bigger learning curve for the existing context API is trudging through myriad opinions about whether or not it's a good idea to use it, and, if so, how to use it safely.
This proposal being slightly more opinionated seems like it would result in a more gradual learning curve.
|
||
For warnings and React DevTools, it would help if providers and consumers | ||
had a `displayName`. The question is whether it should be required. We could | ||
make it optional, and use a Babel transform to add the name automatically. This |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we make it required, but have the babel plugin add the displayName in the function call automatically? Best of both worlds?
const ThemeContext = React.createContext('light')
↓ ↓ ↓ babel plugin ↓ ↓ ↓
const ThemeContext = React.createContext('light', {
displayName: 'ThemeContext',
})
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that's what I was trying to communicate. Maybe I'll just copy your snippet :D
I was thinking the displayName
property would be assigned to the context object directly, as with other component types:
const ThemeContext = React.createContext('light')
↓ ↓ ↓ babel plugin ↓ ↓ ↓
const ThemeContext = React.createContext('light');
ThemeContext.displayName = 'ThemeContext';
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds fine. I thought making it part of the createContext
call would make it easier to log an error. I don't really care how it's implemented though 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want to make the plugin to output static property, please make it in such fashion
const ThemeContext = React.createContext('light');
if (process.env.NODE_ENV === 'development') {
ThemeContext.displayName = 'ThemeContext';
}
Otherwise statics will prevent tree-shaking. This could be configurable with wrap
option for the transform which would default to true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or, rather,
const ThemeContext = React.createContext('light');
if (process.env.NODE_ENV !== 'production') {
ThemeContext.displayName = 'ThemeContext';
}
to match how we do other checks.
return ( | ||
// The Consumer uses a render prop API. Avoids conflicts in the | ||
// props namespace. | ||
<ThemeContext.Consumer> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed a few of our internal apps started using redux in a way such that they do not connect leaf components but instead just rely on the store being accessible on this.context
and they grab things from there directly. I'm not saying this is a recommended approach just that it is one I've seen taken.
Given that behavior (or other direct context access and not using a context -> props hoist component) what would be the migration story for apps wanting to update and needing to replace that with the new <ThemeContext.Consumer>
?
I realize that's a bit of a loaded question, but it seems like it wouldn't necessarily be something that could be code shifted at all, I imagine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Intuitively, the migration to using connect()+props instead of reading straight out of context would be my first investigation.
A grep like:
$grep -hr this\.context src/
should give you an idea of the amount of effort required for this direction. Hope that helps!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussion around how long existing API would hang around, and implementation for that can be found #2 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you give a static value (like store
) to a context provider, consuming it in a child is basically free. So you can continue to use it for the this.context.store
use case. The only difference is you'll have to use the render prop, instead of accessing it on the instance. Unfortunately this means there's no obvious way to codemod this, but it shouldn't be hard for a human to do the migration.
It might be nice for React to ship an "official" HOC for consuming Context in the lifecycle, so that it can be treated differently in React DevTools (different color or etc). It's already inconvenient to dig through a ton of layers of components when using context-based APIs; needing to add another layer to get context in lifecycle methods will exacerbate the issue. |
static values is still supported. | ||
|
||
Replacing subscription-based patterns in favor of context's built-in change | ||
propgation may require a larger effort. However, as a first step, developers can |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
small typo: propagation
the previous context, and return true if they are different. The problem is | ||
that, unlike props or state, we have no type information. The type of the | ||
context object depends on the component's position in the React tree. You could | ||
perform a shallow comparion of both objects, but that only works if we assume |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
small typo: comparison
(if you plan to do a spellcheck at some point, no worries; I can stop pointing these out. I'm just reading through this document and pointing them out as I find them. By the way, this is great so far! Thank you! ✌️ )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ha your spellchecks are appreciated :)
This is an API overhaul to more closely match the API currently being proposed in reactjs/rfcs#2 The main goals of this work are: - Conform more closely to the upcoming context API, to make it easier for people to migrate off react-broadcast when that API eventually lands - Remove reliance on context entirely, since eventually it'll be gone - Remove ambiguity around "channel"s The new API looks like: const { Broadcast, Subscriber } = createBroadcast(initialValue) <Broadcast value="anything-you-want-here"> <Subscriber children={value => ( // ... )} /> </Broadcast> Instead of providing pre-built <Broadcast> and <Subscriber> components, we provide a createBroadcast function that may be used to create them. See the README for further usage instructions.
This proposes an interface that can be done entirely in a 3rd party library. Then why include context in react at all? import {Provider, Consumer} from 'react-context';
<Provider value={123}>
<Consumer>{value => /* ... */}</Consumer>
</Provider> React is already too big, better separate it in another lib, like you did with |
@streamich This proposal can be implemented as 3rd party library only with current context implementation which is not lying in async rendering idea and will be removed in v17. There's still should be parent/child relationship. |
@streamich Also there is 3rd party polyfill create-react-context |
@TrySound Can't you keep track parent/child relationship in a third party library as well? |
@streamich I can't. Can you? |
First off, great job on the implementation. It looks really nice, and I actually like it more than what's on this RFC – it fully addresses my concerns here. However, the implemented API is moderately different from the API proposed here. Can you comment on the bearing this has on the way the RFC process is supposed to work? There was no "final comment period" per https://github.com/reactjs/rfcs#what-the-process-is, and no mention was made of the changes to the implemented API here. I have no problems with the end result, but the process here doesn't seem to have followed what was described. |
I think the plan was to land the change now so we can start testing it internally, but hold off the final API decision until the actual release. But yeah, this means RFC should’ve probably stayed open until we do that. |
Great. Shall we reopen then? |
Oops, never mind. Guess it’d have to be a new PR. |
I'll bring it up that we should do this for future RFCs (or amend the process description). I don't think it makes sense to introduce more bureaucracy now that it's already merged though. |
@taion In my mind, merged means "accepted" but not necessarily "completed." Thanks for the feedback! If you have other comments please open a PR against the existing document. I'm sure we'll get the hang of this process eventually :D |
Internal testing can be done off an unmerged branch though, no? |
That's pretty hard with our continuous release model. We prefer to always land changes in master and hide them behind feature branches instead. |
I think @gaearon's point is right. We should have just left the PR open while the strawman implementation was around, then gone through the "final comment period" and all the rest before accepting the RFC and shipping the new code. |
This is an API overhaul to more closely match the API currently being proposed in reactjs/rfcs#2 The main goals of this work are: - Conform more closely to the upcoming context API, to make it easier for people to migrate off react-broadcast when that API eventually lands - Remove reliance on context entirely, since eventually it'll be gone - Remove ambiguity around "channel"s The new API looks like: const { Broadcast, Subscriber } = createBroadcast(initialValue) <Broadcast value="anything-you-want-here"> <Subscriber children={value => ( // ... )} /> </Broadcast> Instead of providing pre-built <Broadcast> and <Subscriber> components, we provide a createBroadcast function that may be used to create them. See the README for further usage instructions.
The RFC has been finalized and implemented (with a functional |
(supersedes #1)
A proposal for a new version of context addressing existing limitations.
Rendered
Corresponding React PR: facebook/react#11818
TODO:
displayName
transform would work (New version of context #2 (comment)).