Comments (12)
@alfonsogarciacaro The solution I proposed don't ignore the key
prop.
It asks to React to provide the key it's using internally if not is set.
That's why you see:
.$custom-key
which contains the key information I provided viaprop.Key "custom-key"
.1
which is the key used by react internally
I didn't test if there is any performance penalty by this solution but I don't think there is.
If there is we can indeed, try your proposed solution. :)
from feliz.
I think this is caused by (createObj [ "children" ==> [| value |] ])
We should pass directly the list without any modification to Interop.reactElement
static member inline div xs = Interop.reactElement "div" xs
Code was taken from the second snippet on this comment
from feliz.
@zanaptak Thanks for filing the issue!
@MangelMaxime I don't get it, where is the problem coming from exactly? The only thing I can think of, is that we should not generate a list of children
but instead using a spread:
BAD
React.createElement(div, null, [
React.createElement("h1", null, "Content"),
React.createElement("h2", null, "More content")
])
GOOD
React.createElement(div, null,
React.createElement("h1", null, "Content"),
React.createElement("h2", null, "More content")
)
But I am not sure how to compile a list into a spread in Fable, is that what that [<ParamList>]
is doings?! (which is why we don't need to call Array.ofList
on it?? cc @alfonsogarciacaro
from feliz.
Hum, I didn't saw that there is 2 versions of all the HTML element the helpers... And saw only the one re-creating the children.
I am not sure about this 2 helpers thing. I suspect you added it here in order to not force the user to create a list if he have only one direct child. But it makes the code less consistant and refactoring harder because the code is not always the same.
from feliz.
But I am not sure how to compile a list into a spread in Fable, is that what that [] is doings?! (which is why we don't need to call Array.ofList on it?? cc @alfonsogarciacaro
Yes this is indeed what [<ParamList>]
is made for
from feliz.
@Zaid-Ajaj I can't find a way to use the spread syntax when using the children
property.
It's really strange because when I dump the instance values between our version and a spread version they both don't have the key
filled.
A possible solution is to use Children
API from React:
React.Children.toArray
Another pretty self-explanatory utility. toArray converts the children object to an array. It also assigns a key to each child to scope them to the input array. This is useful if you need to reorder or slice the children object.
type ReactChildren =
abstract toArray: ReactElement -> ReactElement seq
abstract toArray: ReactElement seq -> ReactElement seq
type IReactApi =
abstract createElement: comp: obj * props: obj -> ReactElement
abstract createElement: comp: obj * props: obj * [<ParamList>] children: ReactElement seq -> ReactElement
abstract Children : ReactChildren
[<Global("React")>]
let reactApi : IReactApi = jsNative
type prop =
static member children (elems: ReactElement seq) =
Interop.mkAttr "children" (reactApi.Children.toArray elems)
Like that React will add the missing key
for us:
let view =
Html.div [
// attr.className "button"
attr.children [
Html.div [
attr.content "1"
attr.key "custom-key"
]
Html.div [
attr.content "2"
]
]
]
gives:
from feliz.
Yes, ParamList
is equivalent to ParamArray
and spreads the arguments. It should actually be ParamSeq
because it accepts any seq since Fable 2 but it was like that in Fable 1 so I kept the name.
BTW, Fable needs access to the list elements at compile time for proper spreading. When not possible, it uses the JS spread operator
...
. This is one of the reasons all functions in Fable.React.Standard are inlined.
from feliz.
Thanks for explanation @alfonsogarciacaro, this works nicely when the list is in it's own parameter but not when it is a property of a larger object because it wouldn't make sense like @MangelMaxime said:
I can't find a way to use the spread syntax when using the children property.
I was thinking of extracting the children property from props and then apply to a parameter with ParamList
but I wasn't sure if Fable would beta-reduce the lookup operation all the way to a simple list spread (especially if the list has conditional rendering based on runtime information)
@MangelMaxime your solution looks great! I will give it a shot π
from feliz.
Warnings are gone! thanks a lot @MangelMaxime
@zanaptak Can you give it a try in v0.19?
from feliz.
Yes, you can extract the children
property before passing it to the React. A dirty way of doing that could be (note I'm removing inline
because it's better not to inline so much code):
let [<Emit("$0 in $1")>] isKeyIn (key: string) (o: obj): bool = jsNative
let [<Emit("delete $1[$0]")>] deleteKeyFrom (key: string) (o: obj): unit = jsNative
module Interop =
let createElement name (properties: IReactProperty list) : ReactElement =
let props = keyValueList CaseRules.LowerFirst properties // Inlining only this part can help optimizations from the compiler
if isKeyIn "children" props then
let children = props?children
deleteKeyFrom "children" props
ReactBindings.React.createElement(name, props, children)
else
ReactBindings.React.createElement(name, props, [])
BTW, the key
prop is one of the two main heuristics used by React for the tree diffing so I wouldn't just ignore it. Users should still have the possibility of adding a key when dealing with actual collections. This is important when having a large table with filters or sorting for example.
from feliz.
Yeah we can try the solution Alfonso proposed, for now this is the simplest one without helper code π
from feliz.
@Zaid-Ajaj Yep fixed, thanks. π
from feliz.
Related Issues (20)
- Q: interesting
- add vitest to template
- useElmish vs useReducer HOT 4
- Feedback on missing docs for newcomers HOT 1
- ReactComponentAttribute for props list HOT 2
- Q: Documentation on breaking changes in 2.6? [WAS Updating Feliz.UseListener to Feliz 2.6.0] HOT 4
- CSS overflow-anchor property HOT 1
- Error with Feliz 2.7 HOT 2
- Making UseElmish's dispatch function stable
- Feliz.Markdown escapeHtml doesn't seem to work HOT 1
- UseElmish: Failed to resolve import "use-sync-external-store/shim" HOT 3
- `react-markdown` removes the `escapeHtml` property HOT 1
- Clarification and Potential Improvement on PR #480 useEffectOnce behavior HOT 5
- Expanding Feliz.Rechart HOT 3
- Component created with a forwardRef that has generic type parameters loses state HOT 2
- "Directory import use-sync-external-store\shim is not supported" in UseElmish.fs.js HOT 2
- Use with Elmish documentation is lacking integration HOT 2
- Enhance Handling of F# Record Types as Props in ReactComponent Attribute HOT 4
- Explore if Feliz.CompilerPlugin can support POJO made using `[<ParamObject>]`
- prop.pattern produces invalid html HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from feliz.