-
Notifications
You must be signed in to change notification settings - Fork 349
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
typed keys 2 #813
base: main
Are you sure you want to change the base?
typed keys 2 #813
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -283,9 +283,12 @@ describe("React", () => { | |
act(() => { | ||
ReactDOM.Client.render( | ||
root, | ||
<React.Fragment key=?title> | ||
<div> "Child"->React.string </div> | ||
</React.Fragment>, | ||
[| | ||
<React.Fragment key=?title> | ||
<div> "Child"->React.string </div> | ||
</React.Fragment>, | ||
|] | ||
->React.array, | ||
) | ||
}); | ||
|
||
|
@@ -309,9 +312,12 @@ describe("React", () => { | |
}; | ||
|
||
let render = author => | ||
<div key={author.Author.name}> | ||
<div> <img src={author.imageUrl} /> </div> | ||
</div>; | ||
[| | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess this exposes the downside you talked about in the description. I think this is a pretty big limitation, as you can't write this anymore: module Foo = {
[@react.component]
let make = (~id) => {
<div key=id />;
};
};
module Bar = {
[@react.component]
let make = () => {
let ks = Array.init(10, string_of_int);
<> {Array.map(ks, id => <Foo id />)} </>;
};
}; Check the error:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe the keys have to be added directly in the elements that are part of the list, so the keys added to the Check the console warnings from React in this JS snippet, adapted from yours: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This compiles fine, and it'll guarantee the keys are passed correctly to React: module Foo = {
[@react.component]
let make = () => {
<div />;
};
};
module Bar = {
[@react.component]
let make = () => {
let ks = Array.init(10, string_of_int);
<div> {Array.map(ks, id => <Foo key=id />)->React.array} </div>;
};
}; There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indeed, key needs to be on the call-site: |
||
<div key={author.Author.name}> | ||
<div> <img src={author.imageUrl} /> </div> | ||
</div>, | ||
|] | ||
->React.array; | ||
|
||
act(() => { | ||
ReactDOM.Client.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.
Having
element
andelementKeyed
as a completely different type was the main problem that @davesnx and I were running into. There are legit use-cases for supplying a key to an element that is outside of an array and to prevent that at this level would be wrong IMO.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 you share some specific examples please? I could only find 1 example on the whole Ahrefs codebase, of a function that was generating some element, and it could be easily fixed.
To me it's more a line of tradeoffs between approaches than right or wrong. Adding a type variable to
element
has some implications as well in terms of error messages, type complexity, and general dev experience. It also will break more existing code. Some of the impact can be seen already in #812, where a lot more code has to be modified. I can imagine several 3rd party libs out there expectelement
to be a type without variables.I would love to see the approach on #812 applied on Ahrefs monorepo so that we can have more information about how a migration would look like (both for the monorepo code and the opam libs) and how the errors will show with
element('a)
. That way, we can compare both approaches in a more complete way?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 most common usages of
key
in React that I have used (outside of arrays) are:<input>
should be tied to a stateful value from its parent and reset if that state is changed.<div>
) then React might cause unnecessary re-renders when a components sibling changes.Yeah! This is a great call and I can try and whip something up for 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.
@jchavarri I've been hitting enough blockers to try and get a PoC going for you today that I'm going to take a little break and come back to it later. I did a few things on my fork of the PR as well if you want to check them out.