GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — unsafePerformEffect component · Issue #41 · purescript-react/purescript-react-basic-hooks

unsafePerformEffect component #41

New issue
Copy link
New issue
Copy link
Open
Open
unsafePerformEffect component#41
Copy link

Description

@jamesdbrock
jamesdbrock
opened on Nov 4, 2020
Issue body actions

Your initial "actual" example is a great way to write it -- keeping the PS bits effectful and running unsafePerformEffect once at the top level where next.js can pick it up. A component library could similarly expose both the effectful version (which might support a generic type constrained with type classes) alongside a fully applied version which chooses a type for some common use case.

Btw, this is explained briefly in the docs, but if that was confusing or not enough info let me know.

Originally posted by @spicydonuts in #12 (comment)

Activity

  1. maddie927 commented on Nov 4, 2020

    @maddie927
    maddie927
    on Nov 4, 2020
    Member
    More actions

    hmmm?

  2. jamesdbrock commented on Nov 4, 2020

    @jamesdbrock
    jamesdbrock
    on Nov 4, 2020
    MemberAuthor
    More actions

    ...continued...

    I suggest that the documentation for component should specifically encourage users to call it in unsafePerformEffect at the top level.

    No-one will believe that calling unsafePerformEffect is the right thing to do unless instructed that way. I was very confused about this until I found this comment in this issue.

  3. maddie927 commented on Nov 4, 2020

    @maddie927
    maddie927
    on Nov 4, 2020
    Member
    More actions

    I wouldn't say it's the right thing to do. I prefer the "app bootstrap effect" pattern that's been used in examples (which I've unfortunately broken, but you can switch the git tag to the last major version to find them).

    Definitely need a lot of documentation work, I'll leave this open. But yeah, I recommend using main to effectfully construct your root component, and construct the components each child component depends on there in that child's own component creation effect. This is what the Component props alias is for.

    Reacted by James Brock
  4. maddie927 commented on Nov 4, 2020

    @maddie927
    maddie927
    on Nov 4, 2020
    Member
    More actions

    For example:

    main = do
      app <- mkApp
      render (app unit)
    
    mkApp = do
      ctx <- createContext ...defaultCtxValue
      child <- mkChild ctx
      component "App" \_ -> React.do
        ...
        pure $ provider ctx currentCtxValue [ ...more stuff ]
    
    mkChild ctx = do
      component "App" \_ -> React.do
        xyz <- useContext ctx
        pure ...
    Reacted by James Brock, Dennis Gosnell, Pete Murphy and Edgar Rodriguez
  5. pete-murphy commented on Feb 8, 2021

    @pete-murphy
    pete-murphy
    on Feb 8, 2021
    Member
    More actions

    I was recently trying to use useContext in a purescript-cookbook recipe to implement a react-router-style Link component. The Link might be used in any leaf node of the app, so I was initially using unsafePerformEffect to avoid threading the context through. After reading this thread, I thought better of it and refactored to use a ReaderT context wrapper around Component, but now I'm thinking that's not really worth the overhead and I should just thread the context through explicitly as you recommend 😅 .

    I'm curious though, since I've only used the library for small examples, what approach you would recommend if you find yourself needing a context at many leaf nodes of a large app. Would you end up using unsafePerformEffect? Or does the ReaderT approach make sense? Or is the situation just an anti-pattern that should be avoided? (It seems like wire-react-router avoids using Context, but I haven't yet figured out how that library works.)

    Reacted by James Brock and jtomas
  6. maddie927 commented on Feb 8, 2021

    @maddie927
    maddie927
    on Feb 8, 2021
    Member
    More actions

    We use unsafePerformEffect, partly because it matches the JS convention and we transitioned from a JS app initially, but also because it can be more convenient with lots of leaves. But it does occasionally bite us with unexpected component remounts. That's just a cost you have to manage if you go that route, just like you would in a JS React app.

    Your ReaderT example is probably the best approach though, if you're starting from scratch. Maybe the react-basic-hook Component type should be type Component props = ReaderT (RouterContext) Effect (props -> JSX) to encourage that pattern. Or at least expose a ComponentT of that type. You'd have to redefine it with explicit types in your app anyway.

    Reacted by Pete Murphy, James Brock, Mark Eibes, Edgar Rodriguez and Mohammad Hadi Aliakbar
  7. d0liver commented on Nov 2, 2026

    @d0liver
    d0liver
    on Nov 2, 2026
    More actions

    7. We use unsafePerformEffect, partly because it matches the JS convention and we transitioned from a JS app initially, but also because it can be more convenient with lots of leaves. But it does occasionally bite us with unexpected component remounts. That's just a cost you have to manage if you go that route, just like you would in a JS React app.
    Your ReaderT example is probably the best approach though, if you're starting from scratch. Maybe the react-basic-hook Component type should be type Component props = ReaderT (RouterContext) Effect (props -> JSX) to encourage that pattern. Or at least expose a ComponentT of that type. You'd have to redefine it with explicit types in your app anyway.

    I'm curious how the unsafePerformEffect version ends up causing remounts? It seems like all of those effects would happen as the app is loading up and then all of the references would end up effectively constant? Like, maybe this happens when modules are being loaded dynamically or component creation is dynamic?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402520 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.