-
Notifications
You must be signed in to change notification settings - Fork 66
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
Document process of using a third party react component #84
Comments
Hi @danyx23! You're right, we have the pieces to easily import React components but we're missing the guide to do it. There are currently two ways to do it:
EDIT: @danyx23 documented how to use 3rd party React components. You can also see below an example of importing HOC components. |
Hi @alfonsogarciacaro, thank your for your reply! How do you suggest to go forward with this? Should I create a PR with an initial draft of a documentation document in the docs folder of this repo that outlines how to use a third party react component? I am relatively new to Fable and have only used React a little bit - are there areas that are more tricky, like HOCs or similar somewhat advanced features of React? |
This is funny, I was about to write that I hadn't used React HOCs so I didn't know, but just today I had to use them in my project and realized we're missing a helper in fable-react. I think we could add something like this: open Fable.Core
open Fable.Import.React
open Fable.Helpers.React
open Fable.Helpers.React.Props
// Helper to be added to fable-react
let importHigherOrderComponent<[<Pojo>]'P> (importMember: string) (importPath: string) (fn: 'P->ReactElement): ComponentClass<'P> = jsNative
type [<Pojo>] MyProps =
{ index: int; value: string }
let SortableItem: ComponentClass<MyProps> =
importHigherOrderComponent "SortableElement" "react-sortable-hoc" (fun p ->
li [] [str p.value])
// To be used like...
let render () =
from SortableItem { index = 1; value = "foo" } [] But I'm not sure about a few things:
@zaaack @MangelMaxime what do you think? @danyx23 About the documentation, if you could send a PR that'd be great. Don't worry too much about the details, we can work on that later together. The important thing to keep in mind is Fable compiles directly to JS, not JSX. So usually calling |
I never used HOC so I don't know and don't really understand the hight order think. |
@MangelMaxime They're used for example for react-sortable-hoc. |
Please please don't call it higher order. Let's try to think hard for a
serious name
Alfonso Garcia-Caro <[email protected]> schrieb am Di., 17. Apr.
2018, 23:11:
… @MangelMaxime <https://github.com/MangelMaxime> They're used for example
for react-sortable-hoc
<https://github.com/clauderic/react-sortable-hoc#usage>.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#84 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AADgNNPbIEGEVTfPgffrY4xQoNR3xKdgks5tplpogaJpZM4TVog4>
.
|
@alfonsogarciacaro cool I'll draft a PR in the next few days. I can't really comment on the finer points yet but I'll go over the docs again and look at some usage, maybe I will have a bit more input then. @forki it's a silly name but it what is used in the official react docs: https://reactjs.org/docs/higher-order-components.html. As such I would stay with higher order components as that is what people coming from react would be looking for and how third party components that follow this pattern would describe themselves. |
I know react-sortable-hoc, but never use it before. I'm OK with the naming, but not sure about the details, it's a rare case for me, but it looks really useful. |
Thanks a lot for your comments! Yes, so far we've tried to closely follow the React terminology to prevent mismatches with React documentation. We should keep the reference to HOC in this case here too. |
I forgot to mention @vbfox to know his opinion about the helper for React HOCs (please see comment above). |
I added a first draft of the docs - please let me know what you think! |
Did you make any progress on the importHigherOrderComponent? Was look for a way to integrate react-sortable-hoc into my project to day and found this thread but couldn't figure out whether you have implemented it y a different name |
Look at this comments: #84 (comment) I think it should give you a solution |
@runefs We haven't added the helper yet to Fable.React but here's how I'm using react-sortable-hoc in my project, hope it helps: Using react-sortable-hoc from Fableopen Fable.Helpers.React
open Fable.Core.JsInterop
/// Ugly helper that should be moved to fable-react
let inline hocOfImport<'P> (importMember: string) (importPath: string) (fn: 'P->ReactElement): ComponentClass<'P> =
!!((import importMember importPath) $ fn)
// let arrayMove(xs: 'a[], oldIndex: int, newIndex: int): 'a[] = importMember "react-sortable-hoc"
type SortableElementProps<'a> =
{
// SortableElement HOC props (cannot be used by wrapped component)
// https://github.com/clauderic/react-sortable-hoc#sortableelement-hoc
index: int
disabled: bool
// Custom props
rowIndex: int
key: string
value: 'a
handle: ComponentClass<unit>
renderItem: ComponentClass<unit> -> int -> 'a -> ReactElement
}
type SortEnd =
{ oldIndex: int
newIndex: int }
type SortableContainerProps<'a> =
{
// SortableContainer HOC props (cannot be used by wrapped component)
// https://github.com/clauderic/react-sortable-hoc#sortablecontainer-hoc
onSortEnd: SortEnd->unit
lockAxis: string
// Custom props
items: 'a list
handle: ComponentClass<unit>
useDragHandle: bool
renderItem: ComponentClass<unit> -> int -> 'a -> ReactElement
renderList: ReactElement list -> ReactElement
disabled: bool
}
let mkSortableHandle (f: unit -> ReactElement) =
hocOfImport "SortableHandle" "react-sortable-hoc" f
let mkSortableElement<'a> () =
hocOfImport "SortableElement" "react-sortable-hoc"
(fun (p: SortableElementProps<'a>) -> p.renderItem p.handle p.rowIndex p.value)
let mkSortableContainer<'a> (sortableElement: ComponentClass<SortableElementProps<'a>>) =
hocOfImport "SortableContainer" "react-sortable-hoc"
(fun (p: SortableContainerProps<'a>) ->
p.items |> List.mapi (fun i v ->
let a =
{
index = i
disabled = p.disabled
rowIndex = i
key = "item-" + string i // TODO: unique keys not depending on order
value = v
handle = p.handle
renderItem = p.renderItem
}
from sortableElement a [])
|> p.renderList)
type SortableComponentProps<'a> =
{
renderHandle: unit->ReactElement
renderItem: ComponentClass<unit> -> int -> 'a -> ReactElement
renderList: ReactElement list -> ReactElement
items: 'a list
/// oldIndex: int -> newIndex: int -> unit
handleSortChanged : int -> int -> unit
disabled: bool
}
type SortableComponent<'a>(p) =
inherit React.PureComponent<SortableComponentProps<'a>, unit>(p)
// Cache the SortableContainer HOC in the constructor so it's only necessary to build it once
let sortableContainer = mkSortableElement () |> mkSortableContainer
let sortableHandle = mkSortableHandle p.renderHandle
override this.render() =
from sortableContainer
{
// arrayMove(List.toArray this.props.items, i.oldIndex, i.newIndex)
onSortEnd = fun i -> this.props.handleSortChanged i.oldIndex i.newIndex
lockAxis = "y"
items = this.props.items
handle = sortableHandle
useDragHandle = true
renderItem = this.props.renderItem
renderList = this.props.renderList
disabled = this.props.disabled
} []
/// handleSortChanged: oldIndex: int -> newIndex: int -> unit
let mkSortable
(enabled: bool)
(renderList: ReactElement list -> ReactElement)
(renderItem: ComponentClass<unit> -> int -> 'a -> ReactElement)
(renderHandle: unit -> ReactElement)
(items: 'a list)
(handleSortChanged: int -> int -> unit) =
ofType<SortableComponent<'a>,_,_>
{
renderHandle = renderHandle
renderItem = renderItem
renderList = renderList
items = items
handleSortChanged = handleSortChanged
disabled = not enabled
} [] |
Using a discriminated union props type as documented in using-third-party-react-components.md, how do you add support for IHTMLProp? |
Unfortunately this involves a bit of a trick at the moment. When passing the props to react we need to convert them to a JS object, which is done with fable-react/src/Fable.React.Props.fs Lines 379 to 387 in 69ec32d
|
I think one of the big advantages of using Fable and React over e.g. Elm is that it is possible to use an ocean full of ready made React components. However, it is somewhat unclear what needs to be done to declare the required props etc. to use a third party React component. It would be great if this repo in the readme or the Fable docs could have a section on how to do this.
I don't know what the potential issues are with various kinds of e.g. Higher Order Components etc but it might be worth spelling these out explicitly as well. Please let me know if there is anything I can help with in particular to bring this forward.
The text was updated successfully, but these errors were encountered: