-
Notifications
You must be signed in to change notification settings - Fork 47k
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
Add Fragment as a named export to React #10783
Conversation
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.
Looks good... except you wrote too many tests. How dare you!
); | ||
}); | ||
|
||
it('should render via native renderer', () => { |
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 the noop renderer is fine :D This doesn't touch any renderer-specific code.
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.
Should have said so sooner! :'(
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’m sorry :( Didn’t know you were struggling with this. If something’s not renderer specific, we usually just test with the noop renderer. Except for older tests, which use React DOM.
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.
Gotcha, good to know! :)
Let's hold off on documentation until we're ready to release it. Also shouldn't merge this until after 16. |
Doesn’t it mean we’ll create two fibers for every fragment? One for the wrapper and one for the fragment itself. Seems unfortunate. |
@gaearon Yes, but I think this is fine for demo purposes and experimenting at FB. We can optimize it later. |
Although @clemmy if you want to do it the "right" way and avoid the extra fiber, I'm happy to merge that, too :D |
3e44980
to
66726c2
Compare
The link 404 😲 And IIRC, "<></> fragment syntax to JSX" is still under discussion, or you mean it will be accepted to JSX2.0? |
Thought this was the case but then I remembered we don’t create an extra Fragment fiber for an array returned from render. For the same reason we don’t create an extra Fragment fiber for the children of a host component. It just becomes that fiber’s child set. So, we could turn |
Could still be worthwhile for other reasons though |
This is what I meant. But I agree it doesn't block this PR. |
@NE-SmallTown Oops! The link I posted basically just mentions some quirks regarding the |
I though |
Or |
@trueadm I believe that's more of an implementation detail? The reason I'm pushing for this named export to be merged in ASAP is to save a bit of headache when rolling out fragment syntax changes. I'd be happy to change it to |
Would it be hard to implement |
The branching on string type happens here. We could check for |
@clemmy It is an implementation detail, but an important one in my opinion. Babel could instead compile to
|
Could you elaborate on this? How would the export help for the syntax? My understanding is that desugaring JSX to <>hi</>
// How do we know it's React.Fragment and not something else?
React.createElement(React.Fragment, null, 'hi') Whereas if we use a string, we don’t have this problem. <>hi</>
// Works with any pragma.
React.createElement('#fragment', null, 'hi') Why is merging the export helpful in this case? I thought that, if we went with the |
cc @developit, since JSX fragments are important for other libraries that utilize JSX like Preact |
I say we merge this as-is and decide on the implementation details later. We want to start trying out the fragment syntax at Facebook ASAP. |
I like the |
If we only need to add it to try it at FB, we could hack it into the internal |
But yes, either that, or let’s put it behind a feature flag. I don’t want this to become a public API before we’re truly committed to it. |
I'm fine with hacking it onto the export, too. I didn't realize we were still debating whether to export |
* Add Fragment as a named export to React * Remove extra tests for Fragment * Change React.Fragment export to be a string '#fragment' * Fix fragment special case to work with 1 child * Add single child test for fragment export * Move fragment definition to ReactEntry.js and render components for key warning tests * Inline createFiberFromElementType into createFiberFromElement * Update reconciliation to special case fragments * Use same semantics as implicit childsets for ReactFragment * Add more fragment state preservation tests * Export symbol instead of string for fragments * Fix rebase breakages * Re-apply prettier at 1.2.2 * Merge branches in updateElement * Remove unnecessary check * Re-use createFiberFromFragment for fragment case * Simplyify branches by adding type field to fragment fiber * Move branching logic for fragments to broader methods when possible. * Add more tests for fragments * Address Dan's feedback * Move REACT_FRAGMENT_TYPE into __DEV__ block for DCE * Change hex representation of REACT_FRAGMENT_TYPE to follow convention * Remove unnecessary branching and isArray checks * Update test for preserving children state when keys are same * Fix updateSlot bug and add more tests * Make fragment tests more robust by using ops pattern * Update jsx element validator to allow numbers and symbols * Remove type field from fragment fiber * Fork reconcileChildFibers instead of recursing * Use ternary if condition * Revamp fragment test suite: - Add more coverage to fragment tests - Use better names - Remove useless Fragment component inside tests - Remove useless tests so that tests are more concise * Check output of renderer in fragment tests to ensure no silly business despite states being preserved * Finish implementation of fragment reconciliation with desired behavior * Add reverse render direction for fragment tests * Remove unneeded fragment branch in updateElement * Add more test cases for ReactFragment * Handle childless fragment in reconciler * Support fragment flattening in SSR * Clean up ReactPartialRenderer * Warn when non-key and children props are passed to fragments * Add non-null key check back to updateSlot's array's case * Add test for positional reconciliation in fragments * Add warning for refs in fragments with stack trace
function validateFragmentProps(fragment) { | ||
currentlyValidatingElement = fragment; | ||
|
||
for (const key of Object.keys(fragment.props)) { |
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.
We shouldn't have used this. It introduces reliance on Symbol
which we don't currently require.
I think we should add a lint against for ... of
as it's easy to use accidentally and it's not obvious what it compiles down to.
good to go! |
I have some questions, anybody can explain it more in detail? https://reactjs.org/docs/react-component.html#fragments
render() {
return (
<React.Fragment>
<li>First item</li>
<li>Second item</li>
<li>Third item</li>
</React.Fragment>
);
}
<React.Fragment>
<li key="A">First item</li>
<li key="B">Second item</li>
<li key="C">Third item</li>
</React.Fragment> |
@xgqfrms-gildata No keys are required in The wording in the documentation is a bit convoluted since the array syntax used to be called fragments. To make it clearer: Instead of
It should be
|
@clemmy Thanks for your time.
|
This PR is a part of the bigger change to introduce
<></>
fragment syntax to JSX. With this named export, we'll be able to de-sugar<></>
intoReact.createElement(React.Fragment)
calls.UPDATE:
Summary of discussions in PR:
We want to align fragment with array behavior.
You can think of it as the quantum theory of fragments. It has both array-like and element-like properties. 😆