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

Mixed-depth shallow rendering mode #250

Open
lelandrichardson opened this issue Mar 11, 2016 · 8 comments
Open

Mixed-depth shallow rendering mode #250

lelandrichardson opened this issue Mar 11, 2016 · 8 comments

Comments

@lelandrichardson
Copy link
Collaborator

lelandrichardson commented Mar 11, 2016

We could implement an option expand to shallow that allowed you to specify components that you'd like to "expand" the shallow render tree into, while all other components are considered leaf nodes.

function D() {
  return <div className="d" />
}
function C() {
  return <div className="c" />
}
function B(props) {
  return (
    <div className="b">
      <div>B</div>
      {props.children}
    </div>
  );
}
function A(props) {
  return (
    <B>
      <C />
      <D />
      {props.children}
    </B>
  );
}
const wrapper = shallow(<A>Root</A>, { expand: [B, C] });
wrapper.debug();

would output something like this:

<A>
  <B>
    <div className="b">
      <div>B</div>
      <C>
        <div className="c">A</div>
      </C>
      <D />
      Root
    </div>
  </B>
</A>
@ljharb
Copy link
Member

ljharb commented Mar 11, 2016

Wouldn't this end up being more like mountUntil? ie, you'd render the entire tree and only stop when you found the expand elements - whereas mount only stops when it finds native HTML elements.

It seems closer to a partial mount to me, than a shallow render, but maybe I'm missing some of the semantic differences.

@lelandrichardson
Copy link
Collaborator Author

@ljharb mount indicates that it will actually mount onto a root DOM node. shallow only calls componentWillMount and render, getting the render tree, but not doing anything with it.

@ljharb
Copy link
Member

ljharb commented Mar 11, 2016

hm, ok - so then mount is more like "shallow but only stop at native DOM elements" + "attach to the DOM"?

If so then this new thing maybe should be a new top-level thing - that mount calls into?

@lelandrichardson
Copy link
Collaborator Author

@ljharb i'm not sure that's a good way to describe mount. mount uses the same renderer that react-dom itself uses. It makes perfect sense to just use that directly (like we are doing right now).

Because this method is "opt in"... ie, you have to provide all of the components you want the renderer to expand, I think having this on shallow still makes the most sense...

@sjdemartini
Copy link

I like that this solution allows the user to specify which components should be shallow rendered in the subtree (compared to #249), which is useful for keeping the spec more isolate. However, #249 has the advantage that it will work for un-exported components in the root component's subtree, as are often used with stateless functional components. This will require that we export anything we want to expand, right?

@lelandrichardson
Copy link
Collaborator Author

@sjdemartini that is true. You could similarly provide a collapse option to shallow that would be the inverse, where you would manually specify the components that you would want it to stop at

@sjdemartini
Copy link

Nice, yeah, a collapse option with #249 sounds like an awesome idea.

@lasekio
Copy link

lasekio commented Aug 1, 2016

I've made PR to React to support similar functionality in Shallow Renderer itself:

facebook/react#5513

But Facebook doesn't seem to be interested. Another problem is that original shallow renderer doesn't support functional components (primitives) because it doesnt have to - to test primitives call it and check output is enough.

The good idea would be build own shallow renderer outside react. I think it is possible but I React doesnt expose all internals (like ReactChildReconciler) and it would be hard to use this renderer outside node env, when we cannot reach internals like require('react/..../SomeInternal').

Package could contain react codebase which is not desirable. React should stay as peer dependency.

So... We'd need to build our own shallow renderer. It is possible but really hard to accomplish.

Any ideas? Maybe we can convince React team to merge my PR? Or provide another way to partial deep render?

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

4 participants