Skip to content
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

Support for custom renderers #57

Open
yuchi opened this issue Aug 7, 2015 · 6 comments
Open

Support for custom renderers #57

yuchi opened this issue Aug 7, 2015 · 6 comments
Assignees
Milestone

Comments

@yuchi
Copy link

yuchi commented Aug 7, 2015

Because Resolver.render has an hard dependency on React.render it cannot be used with (for example) react-titanium or react-blessed.

An initial thought is to transform

class Resolver {
  static render(element, node, instance = new Resolver()) {
    React.render((
      <Container resolver={instance}>
        {element}
      </Container>
    ), node);

    return instance;
  }
}

to

class Resolver {
  static wrap(element, instance = new Resolver()) {
    return (
      <Container resolver={instance}>
        {element}
      </Container>
    );
  }
  static render(element, node, instance = new Resolver()) {
    React.render(Resolver.wrap(element, instance), node);

    return instance;
  }
}

so that I can use it with my renderer, such as

import { render } from 'react-titanium';
import { wrap } from 'react-resolver';

class App extends Component { /*...*/ }

render(wrap(<App />));
@yuchi
Copy link
Author

yuchi commented Aug 7, 2015

(We’re talking about React ≥ 0.14 of course)

@ericclemmons
Copy link
Owner

@yuchi That's a good thought. I had similar thoughts along these lines, but still having issues with the v2 branch with v0.14 & React Router v1 (and the issues is most likely that).

TBH, I'm not 100% sure how well the Resolver will apply in those situations. Because React doesn't support async rendering, the current architecture has to recursively reveal the tree for dependencies to resolve.

It's something that'd just have to be tested with those alternatives and see how well it works (or doesn't) and go from there, since the React Native render lifecycle is entirely different than vanilla React.

@ericclemmons ericclemmons modified the milestones: v1, v3 Aug 7, 2015
@yuchi
Copy link
Author

yuchi commented Aug 7, 2015

[…] since the React Native render lifecycle is entirely different than vanilla React

React 0.14 is here to solve that. In fact react-titanium uses the vanilla React reconciliation through its own rendering. That‘s what react native will do too.

@ericclemmons
Copy link
Owner

I guess I just don't actually know how they do it. Setting this for v3 in the meantime.

@ericclemmons
Copy link
Owner

I was working on the v2 branch today & got React v0.14 working.

https://github.com/ericclemmons/react-resolver/tree/v2/examples/react-v0.14

I added some comments in 0a92e51, but I gotta figure out how this will work.

For example, this really only makes sense on the server-side when using require("react-dom/server").renderToString for universal rendering. React Native and everything else can actually just render like normal client-side code just like require("react-dom").render, since there's no need for bootstrapping.

@ericclemmons
Copy link
Owner

My initial idea to handle this will be to introduce something like:

Resolver
  .resolveWith(renderToString, () => <Handler {...state} />)
  .then(({ markup, data }) => ...)
;

Similarly, the client could use:

Resolver.renderWith(render, () => <Handler {...state} />, node);

The problem with the client-side version is that it _currently relies on renderToString to recursively load the whole tree.

The alternative to this is to render into a hidden "portal" via render, let all the data accumulate, then re-render on last time to the actual target node.

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

No branches or pull requests

2 participants