cloudflare / react-gateway

Render React DOM into a new context (aka "Portal")
BSD 3-Clause "New" or "Revised" License
571 stars 72 forks source link

Context is lost #4

Open terinjokes opened 8 years ago

terinjokes commented 8 years ago

When a component is rendered into a <Gateway /> the subtree context is lost.

jamiebuilds commented 8 years ago

It seems to be passing the context through fine: https://github.com/cloudflare/react-gateway/blob/master/test/index.js#L72-L131

Can you create a case that reproduces this issue?

terinjokes commented 8 years ago

Yeah, bit will have to be offline. On Jan 25, 2016 10:09 PM, "James Kyle" notifications@github.com wrote:

It seems to be passing the context through fine: https://github.com/cloudflare/react-gateway/blob/master/test/index.js#L72-L125

Can you create a case that reproduces this issue?

— Reply to this email directly or view it on GitHub https://github.com/cloudflare/react-gateway/issues/4#issuecomment-174850186 .

danielberndt commented 8 years ago

the problem occurs when you rewrite the test case such that the Child doesn't render the Gateway but the Parent does:

class Parent extends React.Component {
      static childContextTypes = {
        textContent: React.PropTypes.string.isRequired
      };

      getChildContext() {
        return {
          textContent: 'Hello from context'
        };
      }

      render() {
        return <Gateway into="dest"><Child/></Gateway>;
      }
    }

This is where unstable_renderSubtreeIntoContainer could come in handy. (Even though it's unstable for good reasons)


Here's why this issue is problematic for my use case: I wanna render an indefinite (= n) amount of portals. Since one GatewayDest can have only one child due to recent changes, I render one Gateway within the Parent. This gateway then renders n absolutely positioned children.

However those children now don't have access to the context defined within the Parent.

srph commented 7 years ago

I'm concerned about this too. Here's a quick workaround I did (in case somebody comes across the issue; it's probably me in a few months):

class PassContext extends React.Component {
  getChildContext() {
    return {
      dragDropManager: this.props.dragDropManager
    };
  }

  render() {
    return this.props.children;
  }
}

PassContext.childContextTypes = {
  dragDropManager: PropTypes.any
}

function X() {
  return (
    <Gateway into="modal">
      <PassContext dragDropManager={this.context.dragDropManager}>
        <Modal2>...</Modal2>
      </PassContext>
    </Gateway>
  );
}

X.contextTypes = {
  dragDropManager: PropTypes.any
}