Git Product home page Git Product logo

Comments (18)

dan-lee avatar dan-lee commented on July 3, 2024 6

After the release of React Hooks I've moved away from react-tree-walker.
I figured that it will be an endless fight to keep up with React. Very ambitious to say the least (just thinking about Suspense, Concurrent mode, etc.)

In the end I decided to go the same way as react-apollo did. Even if it's one more complete render cycle. I simplified it a lot for my use case.

If anyone is interested that's how I've roughly done it.
// server.js

// Preparation for SSR
export const PreloadPromiseContext = React.createContext()

// This will called on page load on SSR
const preload = async tree => {
  const loaders = []
  const registerLoader = loaderConfig => loaders.push(loaderConfig)

  // collect
  ReactDOMServer.renderToStaticMarkup(
    <PreloadPromiseContext.Provider value={{ registerLoader }}>
      {tree}
    </PreloadPromiseContext.Provider>
  )

  // resolve one after another
  // loaders will put responses into global store
  for (const { props, loader } of loaders) {
    await loader(props)
  }
}

// Actual SSR
server.use(async (req, res) => {
  const app = (
    <Provider store={store}>
      <App />
    </Provider>
  )

  await preload(app)

  // use state and markup to render the actual HTML output
  const state = store.getState()
  const markup = ReactDOMServer.renderToString(app)
})

Now this is used in combination with a HoC (could maybe be a hook at some point?) Every component which should preload is wrapped with this.

import PreloadPromiseContext from './server.js'

const resolve = loader => Component => {
  class Resolve extends React.Component {
    static contextType = PreloadPromiseContext

    constructor(props, context) {
      super(props, context)

      if (context && typeof window === 'undefined') {
        // fetch on SSR
        context.registerLoader({ props, loader })
      } else {
        // fetch on client side, to make life easier
        // (you might not need this)
        loader(props)
      }
    }

    render() {
      return <Component {...this.props} />
    }
  }

  return hoistNonReactStatics(Resolve, Component)
}

// Example usage for a component. The result will be put in a global store inside the called function
export default presolve(props => props.store.fetchThings())(MyApp)

from react-tree-walker.

jcampalo avatar jcampalo commented on July 3, 2024 3

Any updates on this? I have problems updating to react 16.6.x which makes react-async-bootstrapper unusable.

from react-tree-walker.

isaachinman avatar isaachinman commented on July 3, 2024 3

@ctrlplusb Any idea when you'll be releasing this? We're using react-tree-walker over at next-i18next. Thanks!

from react-tree-walker.

jaydenseric avatar jaydenseric commented on July 3, 2024 2

React hooks is probably a bigger problem than the context API, a lot of libraries including graphql-react and Apollo have given up on walking React trees.

from react-tree-walker.

jaredLunde avatar jaredLunde commented on July 3, 2024 2

Ah, I see what you mean now. Your solution in graphql-react and the new react-apollo getDataFromTree are interesting. I imagine it's a lot more expensive but the reliability is what matters most I guess.

from react-tree-walker.

jaydenseric avatar jaydenseric commented on July 3, 2024

As another reference, I've recently fixed the graphql-react SSR preload function for React v16.6 context: Diff here.

from react-tree-walker.

ctrlplusb avatar ctrlplusb commented on July 3, 2024

@tadeuszwojcik of course, always happy to keep inline with the latest fixes and enhancements that the Apollo team have applied. Would really appreciate the PR. 👍

from react-tree-walker.

jcampalo avatar jcampalo commented on July 3, 2024

Seems like @ctrlplusb is inactive, it's a bit annoying. Did anyone create a fork and published it on npm?

from react-tree-walker.

oyeanuj avatar oyeanuj commented on July 3, 2024

@isaachinman @jcampalo Did you guys publish a fork by any chance?

from react-tree-walker.

isaachinman avatar isaachinman commented on July 3, 2024

Hi @oyeanuj. Over at next-i18next I had to move away from react-tree-walker entirely due to:

  1. Performance impact.
  2. Unreconcilable issues with context.

It's a bit of a shame, but I think this project is self-aware in that it's not appropriate for every use case.

Good luck!

from react-tree-walker.

oyeanuj avatar oyeanuj commented on July 3, 2024

@isaachinman what did you end up using instead?

from react-tree-walker.

isaachinman avatar isaachinman commented on July 3, 2024

@oyeanuj I took a completely different approach that sidestepped tree traversal entirely. Sorry if that's not helpful.

from react-tree-walker.

jcampalo avatar jcampalo commented on July 3, 2024

@ctrlplusb Please give proper rights to others, we need this fix.

from react-tree-walker.

mschipperheyn avatar mschipperheyn commented on July 3, 2024

Shit. completely stuck on this. Days sunk into this already. What are people using as alternatives?

from react-tree-walker.

dan-lee avatar dan-lee commented on July 3, 2024

@mschipperheyn I didn't personally check it myself, but see this: #46 (comment)

from react-tree-walker.

jdwillemse avatar jdwillemse commented on July 3, 2024

@mschipperheyn I didn't personally check it myself, but see this: #46 (comment)

I tested this and It did not solve this problem.

from react-tree-walker.

jaredLunde avatar jaredLunde commented on July 3, 2024

Does this fork fix the issue for anyone? It has worked for me. If so I can work on a PR w/ the fix I lifted from react-apollo.

https://github.com/jaredLunde/react-tree-walker

from react-tree-walker.

jaredLunde avatar jaredLunde commented on July 3, 2024

Yeah, I mean it's a large part of why I haven't even begun looking at Hooks. I need asynchronous components on the server side more than I need hooks. Unfortunately React.lazy + Suspense is useless until their new server renderer is done in the second half of this year so this will have to do.

from react-tree-walker.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.